App: Apply clang format (part 2)
This commit is contained in:
+9
-10
@@ -35,15 +35,14 @@ using namespace App;
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
|
||||
Color::Color(float red, float green, float blue, float alpha)
|
||||
: r(red)
|
||||
, g(green)
|
||||
, b(blue)
|
||||
, a(alpha)
|
||||
{
|
||||
}
|
||||
: r(red)
|
||||
, g(green)
|
||||
, b(blue)
|
||||
, a(alpha)
|
||||
{}
|
||||
|
||||
Color::Color(uint32_t rgba)
|
||||
: Color{}
|
||||
: Color {}
|
||||
{
|
||||
setPackedValue(rgba);
|
||||
}
|
||||
@@ -159,7 +158,7 @@ bool Color::fromHexString(const std::string& hex)
|
||||
if (hex.size() == 7) {
|
||||
std::stringstream ss(hex);
|
||||
unsigned int rgb;
|
||||
char ch{};
|
||||
char ch {};
|
||||
|
||||
ss >> ch >> std::hex >> rgb;
|
||||
int rc = (rgb >> 16) & 0xff;
|
||||
@@ -176,13 +175,13 @@ bool Color::fromHexString(const std::string& hex)
|
||||
if (hex.size() == 9) {
|
||||
std::stringstream ss(hex);
|
||||
unsigned int rgba;
|
||||
char ch{};
|
||||
char ch {};
|
||||
|
||||
ss >> ch >> std::hex >> rgba;
|
||||
int rc = (rgba >> 24) & 0xff;
|
||||
int gc = (rgba >> 16) & 0xff;
|
||||
int bc = (rgba >> 8) & 0xff;
|
||||
int ac = rgba & 0xff;
|
||||
int ac = rgba & 0xff;
|
||||
|
||||
r = rc / 255.0F;
|
||||
g = gc / 255.0F;
|
||||
|
||||
+4
-4
@@ -72,7 +72,7 @@ struct color_traits
|
||||
}
|
||||
static color_type makeColor(int red, int green, int blue, int alpha = 255)
|
||||
{
|
||||
return color_type{red, green, blue, alpha};
|
||||
return color_type {red, green, blue, alpha};
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -146,7 +146,7 @@ public:
|
||||
template<typename T>
|
||||
static uint32_t asPackedRGBA(const T& color)
|
||||
{
|
||||
color_traits<T> ct{color};
|
||||
color_traits<T> ct {color};
|
||||
return (ct.red() << 24) | (ct.green() << 16) | (ct.blue() << 8) | ct.alpha();
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ public:
|
||||
template<typename T>
|
||||
static uint32_t asPackedRGB(const T& color)
|
||||
{
|
||||
color_traits<T> ct{color};
|
||||
color_traits<T> ct {color};
|
||||
return (ct.red() << 24) | (ct.green() << 16) | (ct.blue() << 8);
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ public:
|
||||
template<typename T>
|
||||
void setValue(const T& q)
|
||||
{
|
||||
color_traits<T> ct{q};
|
||||
color_traits<T> ct {q};
|
||||
set(ct.redF(), ct.greenF(), ct.blueF());
|
||||
}
|
||||
/**
|
||||
|
||||
+151
-121
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <cstdlib>
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
#include <Base/Exception.h>
|
||||
@@ -36,66 +36,66 @@ using namespace App;
|
||||
|
||||
ColorModelPack ColorModelPack::createRedGreenBlue()
|
||||
{
|
||||
ColorModelPack pack{ColorModelBlueGreenRed(),
|
||||
ColorModelGreenYellowRed(),
|
||||
ColorModelBlueCyanGreen(),
|
||||
"Red-Yellow-Green-Cyan-Blue"};
|
||||
ColorModelPack pack {ColorModelBlueGreenRed(),
|
||||
ColorModelGreenYellowRed(),
|
||||
ColorModelBlueCyanGreen(),
|
||||
"Red-Yellow-Green-Cyan-Blue"};
|
||||
return pack;
|
||||
}
|
||||
|
||||
ColorModelPack ColorModelPack::createBlueGreenRed()
|
||||
{
|
||||
ColorModelPack pack{ColorModelRedGreenBlue(),
|
||||
ColorModelGreenCyanBlue(),
|
||||
ColorModelRedYellowGreen(),
|
||||
"Blue-Cyan-Green-Yellow-Red"};
|
||||
ColorModelPack pack {ColorModelRedGreenBlue(),
|
||||
ColorModelGreenCyanBlue(),
|
||||
ColorModelRedYellowGreen(),
|
||||
"Blue-Cyan-Green-Yellow-Red"};
|
||||
return pack;
|
||||
}
|
||||
|
||||
ColorModelPack ColorModelPack::createWhiteBlack()
|
||||
{
|
||||
ColorModelPack pack{ColorModelBlackWhite(),
|
||||
ColorModelGrayWhite(),
|
||||
ColorModelBlackGray(),
|
||||
"White-Black"};
|
||||
ColorModelPack pack {ColorModelBlackWhite(),
|
||||
ColorModelGrayWhite(),
|
||||
ColorModelBlackGray(),
|
||||
"White-Black"};
|
||||
return pack;
|
||||
}
|
||||
|
||||
ColorModelPack ColorModelPack::createBlackWhite()
|
||||
{
|
||||
ColorModelPack pack{ColorModelWhiteBlack(),
|
||||
ColorModelGrayBlack(),
|
||||
ColorModelWhiteGray(),
|
||||
"Black-White"};
|
||||
ColorModelPack pack {ColorModelWhiteBlack(),
|
||||
ColorModelGrayBlack(),
|
||||
ColorModelWhiteGray(),
|
||||
"Black-White"};
|
||||
return pack;
|
||||
}
|
||||
|
||||
ColorModelPack ColorModelPack::createRedWhiteBlue()
|
||||
{
|
||||
ColorModelPack pack{ColorModelBlueWhiteRed(),
|
||||
ColorModelWhiteRed(),
|
||||
ColorModelBlueWhite(),
|
||||
"Red-White-Blue"};
|
||||
ColorModelPack pack {ColorModelBlueWhiteRed(),
|
||||
ColorModelWhiteRed(),
|
||||
ColorModelBlueWhite(),
|
||||
"Red-White-Blue"};
|
||||
return pack;
|
||||
}
|
||||
|
||||
ColorField::ColorField ()
|
||||
ColorField::ColorField()
|
||||
{
|
||||
set(ColorModelBlueGreenRed(), -1.0f, 1.0f, 13);
|
||||
}
|
||||
|
||||
ColorField::ColorField (const ColorModel &rclModel, float fMin, float fMax, std::size_t usCt)
|
||||
ColorField::ColorField(const ColorModel& rclModel, float fMin, float fMax, std::size_t usCt)
|
||||
{
|
||||
set(rclModel, fMin, fMax, usCt);
|
||||
}
|
||||
|
||||
ColorField& ColorField::operator = (const ColorField &rclCF)
|
||||
ColorField& ColorField::operator=(const ColorField& rclCF)
|
||||
{
|
||||
colorField = rclCF.colorField;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ColorField::set (const ColorModel &rclModel, float fMin, float fMax, std::size_t usCt)
|
||||
void ColorField::set(const ColorModel& rclModel, float fMin, float fMax, std::size_t usCt)
|
||||
{
|
||||
auto bounds = std::minmax(fMin, fMax);
|
||||
if (bounds.second <= bounds.first) {
|
||||
@@ -109,34 +109,37 @@ void ColorField::set (const ColorModel &rclModel, float fMin, float fMax, std::s
|
||||
rebuild();
|
||||
}
|
||||
|
||||
void ColorField::setColorModel (const ColorModel &rclModel)
|
||||
void ColorField::setColorModel(const ColorModel& rclModel)
|
||||
{
|
||||
colorModel = rclModel;
|
||||
rebuild();
|
||||
}
|
||||
|
||||
void ColorField::rebuild ()
|
||||
void ColorField::rebuild()
|
||||
{
|
||||
colorField.resize(ctColors);
|
||||
|
||||
std::size_t usStep = std::min<std::size_t>(ctColors / (colorModel.getCountColors() - 1), ctColors - 1);
|
||||
std::size_t usStep =
|
||||
std::min<std::size_t>(ctColors / (colorModel.getCountColors() - 1), ctColors - 1);
|
||||
std::size_t usInd1 = 0;
|
||||
std::size_t usInd2 = usStep;
|
||||
for (std::size_t i = 0; i < (colorModel.getCountColors() - 1); i++) {
|
||||
interpolate(colorModel.colors[i], usInd1, colorModel.colors[i+1], usInd2);
|
||||
interpolate(colorModel.colors[i], usInd1, colorModel.colors[i + 1], usInd2);
|
||||
usInd1 = usInd2;
|
||||
if ((i + 1) == (colorModel.getCountColors() - 2))
|
||||
if ((i + 1) == (colorModel.getCountColors() - 2)) {
|
||||
usInd2 = ctColors - 1;
|
||||
else
|
||||
}
|
||||
else {
|
||||
usInd2 += usStep;
|
||||
}
|
||||
}
|
||||
|
||||
fAscent = float(ctColors) / (fMax - fMin);
|
||||
fAscent = float(ctColors) / (fMax - fMin);
|
||||
fConstant = -fAscent * fMin;
|
||||
}
|
||||
|
||||
// fuellt das Array von Farbe 1, Index 1 bis Farbe 2, Index 2
|
||||
void ColorField::interpolate (Color clCol1, std::size_t usInd1, Color clCol2, std::size_t usInd2)
|
||||
void ColorField::interpolate(Color clCol1, std::size_t usInd1, Color clCol2, std::size_t usInd2)
|
||||
{
|
||||
float fStep = 1.0f, fLen = float(usInd2 - usInd1);
|
||||
|
||||
@@ -161,28 +164,37 @@ ColorGradientProfile::ColorGradientProfile() = default;
|
||||
|
||||
bool ColorGradientProfile::isEqual(const ColorGradientProfile& cg) const
|
||||
{
|
||||
if (tStyle != cg.tStyle)
|
||||
if (tStyle != cg.tStyle) {
|
||||
return false;
|
||||
if (fMin != cg.fMin)
|
||||
}
|
||||
if (fMin != cg.fMin) {
|
||||
return false;
|
||||
if (fMax != cg.fMax)
|
||||
}
|
||||
if (fMax != cg.fMax) {
|
||||
return false;
|
||||
if (!visibility.isEqual(cg.visibility))
|
||||
}
|
||||
if (!visibility.isEqual(cg.visibility)) {
|
||||
return false;
|
||||
if (tColorModel != cg.tColorModel)
|
||||
}
|
||||
if (tColorModel != cg.tColorModel) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
ColorGradient::ColorGradient ()
|
||||
ColorGradient::ColorGradient()
|
||||
{
|
||||
createStandardPacks();
|
||||
setColorModel();
|
||||
set(-1.0f, 1.0f, 13, ColorBarStyle::ZERO_BASED, Visibility::Default);
|
||||
}
|
||||
|
||||
ColorGradient::ColorGradient (float fMin, float fMax, std::size_t usCtColors, ColorBarStyle tS, VisibilityFlags flags)
|
||||
ColorGradient::ColorGradient(float fMin,
|
||||
float fMax,
|
||||
std::size_t usCtColors,
|
||||
ColorBarStyle tS,
|
||||
VisibilityFlags flags)
|
||||
{
|
||||
createStandardPacks();
|
||||
setColorModel();
|
||||
@@ -202,8 +214,9 @@ std::vector<std::string> ColorGradient::getColorModelNames() const
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
names.reserve(modelPacks.size());
|
||||
for (const auto& it : modelPacks)
|
||||
for (const auto& it : modelPacks) {
|
||||
names.push_back(it.description);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
@@ -214,7 +227,11 @@ void ColorGradient::setProfile(const ColorGradientProfile& pro)
|
||||
rebuild();
|
||||
}
|
||||
|
||||
void ColorGradient::set (float fMin, float fMax, std::size_t usCt, ColorBarStyle tS, VisibilityFlags flags)
|
||||
void ColorGradient::set(float fMin,
|
||||
float fMax,
|
||||
std::size_t usCt,
|
||||
ColorBarStyle tS,
|
||||
VisibilityFlags flags)
|
||||
{
|
||||
auto bounds = std::minmax(fMin, fMax);
|
||||
if (bounds.second <= bounds.first) {
|
||||
@@ -229,74 +246,79 @@ void ColorGradient::set (float fMin, float fMax, std::size_t usCt, ColorBarStyle
|
||||
rebuild();
|
||||
}
|
||||
|
||||
void ColorGradient::rebuild ()
|
||||
void ColorGradient::rebuild()
|
||||
{
|
||||
switch (profile.tStyle)
|
||||
{
|
||||
case ColorBarStyle::FLOW:
|
||||
{
|
||||
colorField1.set(currentModelPack.totalModel, profile.fMin, profile.fMax, profile.ctColors);
|
||||
switch (profile.tStyle) {
|
||||
case ColorBarStyle::FLOW: {
|
||||
colorField1.set(currentModelPack.totalModel,
|
||||
profile.fMin,
|
||||
profile.fMax,
|
||||
profile.ctColors);
|
||||
break;
|
||||
}
|
||||
case ColorBarStyle::ZERO_BASED:
|
||||
{
|
||||
if ((profile.fMin < 0.0f) && (profile.fMax > 0.0f))
|
||||
{
|
||||
colorField1.set(currentModelPack.bottomModel, profile.fMin, 0.0f, profile.ctColors / 2);
|
||||
colorField2.set(currentModelPack.topModel, 0.0f, profile.fMax, profile.ctColors / 2);
|
||||
case ColorBarStyle::ZERO_BASED: {
|
||||
if ((profile.fMin < 0.0f) && (profile.fMax > 0.0f)) {
|
||||
colorField1.set(currentModelPack.bottomModel,
|
||||
profile.fMin,
|
||||
0.0f,
|
||||
profile.ctColors / 2);
|
||||
colorField2.set(currentModelPack.topModel,
|
||||
0.0f,
|
||||
profile.fMax,
|
||||
profile.ctColors / 2);
|
||||
}
|
||||
else if (profile.fMin >= 0.0f)
|
||||
else if (profile.fMin >= 0.0f) {
|
||||
colorField1.set(currentModelPack.topModel, 0.0f, profile.fMax, profile.ctColors);
|
||||
else
|
||||
}
|
||||
else {
|
||||
colorField1.set(currentModelPack.bottomModel, profile.fMin, 0.0f, profile.ctColors);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t ColorGradient::getMinColors () const
|
||||
std::size_t ColorGradient::getMinColors() const
|
||||
{
|
||||
switch (profile.tStyle)
|
||||
{
|
||||
case ColorBarStyle::FLOW:
|
||||
return colorField1.getMinColors();
|
||||
case ColorBarStyle::ZERO_BASED:
|
||||
{
|
||||
if ((profile.fMin < 0.0f) && (profile.fMax > 0.0f))
|
||||
switch (profile.tStyle) {
|
||||
case ColorBarStyle::FLOW:
|
||||
return colorField1.getMinColors();
|
||||
case ColorBarStyle::ZERO_BASED: {
|
||||
if ((profile.fMin < 0.0f) && (profile.fMax > 0.0f)) {
|
||||
return colorField1.getMinColors() + colorField2.getMinColors();
|
||||
else
|
||||
}
|
||||
else {
|
||||
return colorField1.getMinColors();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
void ColorGradient::setColorModel (std::size_t tModel)
|
||||
void ColorGradient::setColorModel(std::size_t tModel)
|
||||
{
|
||||
profile.tColorModel = tModel;
|
||||
setColorModel();
|
||||
rebuild();
|
||||
}
|
||||
|
||||
void ColorGradient::setColorModel ()
|
||||
void ColorGradient::setColorModel()
|
||||
{
|
||||
if (profile.tColorModel < modelPacks.size())
|
||||
if (profile.tColorModel < modelPacks.size()) {
|
||||
currentModelPack = modelPacks[profile.tColorModel];
|
||||
}
|
||||
|
||||
switch (profile.tStyle)
|
||||
{
|
||||
case ColorBarStyle::FLOW:
|
||||
{
|
||||
colorField1.setColorModel(currentModelPack.totalModel);
|
||||
colorField2.setColorModel(currentModelPack.bottomModel);
|
||||
break;
|
||||
}
|
||||
case ColorBarStyle::ZERO_BASED:
|
||||
{
|
||||
colorField1.setColorModel(currentModelPack.topModel);
|
||||
colorField2.setColorModel(currentModelPack.bottomModel);
|
||||
break;
|
||||
}
|
||||
switch (profile.tStyle) {
|
||||
case ColorBarStyle::FLOW: {
|
||||
colorField1.setColorModel(currentModelPack.totalModel);
|
||||
colorField2.setColorModel(currentModelPack.bottomModel);
|
||||
break;
|
||||
}
|
||||
case ColorBarStyle::ZERO_BASED: {
|
||||
colorField1.setColorModel(currentModelPack.topModel);
|
||||
colorField2.setColorModel(currentModelPack.bottomModel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,60 +339,65 @@ ColorLegend::ColorLegend()
|
||||
values.push_back(1.0f);
|
||||
}
|
||||
|
||||
bool ColorLegend::operator == (const ColorLegend &rclCL) const
|
||||
bool ColorLegend::operator==(const ColorLegend& rclCL) const
|
||||
{
|
||||
return (colorFields.size() == rclCL.colorFields.size()) &&
|
||||
(names.size() == rclCL.names.size()) &&
|
||||
(values.size() == rclCL.values.size()) &&
|
||||
std::equal(colorFields.begin(), colorFields.end(), rclCL.colorFields.begin()) &&
|
||||
std::equal(names.begin(), names.end(), rclCL.names.begin()) &&
|
||||
std::equal(values.begin(), values.end(), rclCL.values.begin()) &&
|
||||
outsideGrayed == rclCL.outsideGrayed;
|
||||
return (colorFields.size() == rclCL.colorFields.size()) && (names.size() == rclCL.names.size())
|
||||
&& (values.size() == rclCL.values.size())
|
||||
&& std::equal(colorFields.begin(), colorFields.end(), rclCL.colorFields.begin())
|
||||
&& std::equal(names.begin(), names.end(), rclCL.names.begin())
|
||||
&& std::equal(values.begin(), values.end(), rclCL.values.begin())
|
||||
&& outsideGrayed == rclCL.outsideGrayed;
|
||||
}
|
||||
|
||||
float ColorLegend::getValue (std::size_t ulPos) const
|
||||
float ColorLegend::getValue(std::size_t ulPos) const
|
||||
{
|
||||
if (ulPos < values.size())
|
||||
if (ulPos < values.size()) {
|
||||
return values[ulPos];
|
||||
else
|
||||
}
|
||||
else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
bool ColorLegend::setValue (std::size_t ulPos, float fVal)
|
||||
bool ColorLegend::setValue(std::size_t ulPos, float fVal)
|
||||
{
|
||||
if (ulPos < values.size())
|
||||
{
|
||||
if (ulPos < values.size()) {
|
||||
values[ulPos] = fVal;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Color ColorLegend::getColor (std::size_t ulPos) const
|
||||
Color ColorLegend::getColor(std::size_t ulPos) const
|
||||
{
|
||||
if (ulPos < colorFields.size())
|
||||
if (ulPos < colorFields.size()) {
|
||||
return colorFields[ulPos];
|
||||
else
|
||||
}
|
||||
else {
|
||||
return Color();
|
||||
}
|
||||
}
|
||||
|
||||
// color as: 0x00rrggbb
|
||||
uint32_t ColorLegend::getPackedColor (std::size_t ulPos) const
|
||||
uint32_t ColorLegend::getPackedColor(std::size_t ulPos) const
|
||||
{
|
||||
Color clRGB = getColor(ulPos);
|
||||
return clRGB.getPackedValue();
|
||||
}
|
||||
|
||||
std::string ColorLegend::getText (std::size_t ulPos) const
|
||||
std::string ColorLegend::getText(std::size_t ulPos) const
|
||||
{
|
||||
if (ulPos < names.size())
|
||||
if (ulPos < names.size()) {
|
||||
return names[ulPos];
|
||||
else
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t ColorLegend::addMin (const std::string &rclName)
|
||||
std::size_t ColorLegend::addMin(const std::string& rclName)
|
||||
{
|
||||
names.push_front(rclName);
|
||||
values.push_front(values.front() - 1.0f);
|
||||
@@ -385,7 +412,7 @@ std::size_t ColorLegend::addMin (const std::string &rclName)
|
||||
return colorFields.size() - 1;
|
||||
}
|
||||
|
||||
std::size_t ColorLegend::addMax (const std::string &rclName)
|
||||
std::size_t ColorLegend::addMax(const std::string& rclName)
|
||||
{
|
||||
names.push_back(rclName);
|
||||
values.push_back(values.back() + 1.0f);
|
||||
@@ -400,7 +427,7 @@ std::size_t ColorLegend::addMax (const std::string &rclName)
|
||||
return colorFields.size() - 1;
|
||||
}
|
||||
|
||||
bool ColorLegend::remove (std::size_t ulPos)
|
||||
bool ColorLegend::remove(std::size_t ulPos)
|
||||
{
|
||||
if (ulPos < colorFields.size()) {
|
||||
colorFields.erase(colorFields.begin() + ulPos);
|
||||
@@ -413,7 +440,7 @@ bool ColorLegend::remove (std::size_t ulPos)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ColorLegend::removeFirst ()
|
||||
void ColorLegend::removeFirst()
|
||||
{
|
||||
if (!colorFields.empty()) {
|
||||
colorFields.erase(colorFields.begin());
|
||||
@@ -422,33 +449,36 @@ void ColorLegend::removeFirst ()
|
||||
}
|
||||
}
|
||||
|
||||
void ColorLegend::removeLast ()
|
||||
void ColorLegend::removeLast()
|
||||
{
|
||||
if (!colorFields.empty()) {
|
||||
colorFields.erase(colorFields.end()-1);
|
||||
names.erase(names.end()-1);
|
||||
values.erase(values.end()-1);
|
||||
colorFields.erase(colorFields.end() - 1);
|
||||
names.erase(names.end() - 1);
|
||||
values.erase(values.end() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ColorLegend::resize (std::size_t ulCt)
|
||||
void ColorLegend::resize(std::size_t ulCt)
|
||||
{
|
||||
if ((ulCt < 2) || (ulCt == colorFields.size()))
|
||||
if ((ulCt < 2) || (ulCt == colorFields.size())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ulCt > colorFields.size()) {
|
||||
int k = ulCt - colorFields.size();
|
||||
for (int i = 0; i < k; i++)
|
||||
for (int i = 0; i < k; i++) {
|
||||
addMin("new");
|
||||
}
|
||||
}
|
||||
else {
|
||||
int k = colorFields.size() - ulCt;
|
||||
for (int i = 0; i < k; i++)
|
||||
for (int i = 0; i < k; i++) {
|
||||
removeLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ColorLegend::setColor (std::size_t ulPos, float ucRed, float ucGreen, float ucBlue)
|
||||
bool ColorLegend::setColor(std::size_t ulPos, float ucRed, float ucGreen, float ucBlue)
|
||||
{
|
||||
if (ulPos < names.size()) {
|
||||
colorFields[ulPos] = Color(ucRed, ucGreen, ucBlue);
|
||||
@@ -459,15 +489,15 @@ bool ColorLegend::setColor (std::size_t ulPos, float ucRed, float ucGreen, float
|
||||
}
|
||||
|
||||
// color as 0x00rrggbb
|
||||
bool ColorLegend::setColor (std::size_t ulPos, unsigned long ulColor)
|
||||
bool ColorLegend::setColor(std::size_t ulPos, unsigned long ulColor)
|
||||
{
|
||||
unsigned char ucRed = (unsigned char)((ulColor & 0x00ff0000) >> 16);
|
||||
unsigned char ucRed = (unsigned char)((ulColor & 0x00ff0000) >> 16);
|
||||
unsigned char ucGreen = (unsigned char)((ulColor & 0x0000ff00) >> 8);
|
||||
unsigned char ucBlue = (unsigned char)(ulColor & 0x000000ff);
|
||||
unsigned char ucBlue = (unsigned char)(ulColor & 0x000000ff);
|
||||
return setColor(ulPos, ucRed, ucGreen, ucBlue);
|
||||
}
|
||||
|
||||
bool ColorLegend::setText (std::size_t ulPos, const std::string &rclName)
|
||||
bool ColorLegend::setText(std::size_t ulPos, const std::string& rclName)
|
||||
{
|
||||
if (ulPos < names.size()) {
|
||||
names[ulPos] = rclName;
|
||||
|
||||
+264
-178
@@ -36,7 +36,8 @@
|
||||
namespace App
|
||||
{
|
||||
|
||||
enum class Visibility {
|
||||
enum class Visibility
|
||||
{
|
||||
Default,
|
||||
Grayed,
|
||||
Invisible
|
||||
@@ -44,12 +45,13 @@ enum class Visibility {
|
||||
|
||||
using VisibilityFlags = Base::Flags<Visibility>;
|
||||
|
||||
enum class ColorBarStyle {
|
||||
enum class ColorBarStyle
|
||||
{
|
||||
FLOW,
|
||||
ZERO_BASED
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace App
|
||||
|
||||
ENABLE_BITMASK_OPERATORS(App::Visibility)
|
||||
|
||||
@@ -65,8 +67,8 @@ public:
|
||||
virtual Color getColor(float fVal) const = 0;
|
||||
|
||||
protected:
|
||||
ValueFloatToRGB () = default;
|
||||
virtual ~ValueFloatToRGB () = default;
|
||||
ValueFloatToRGB() = default;
|
||||
virtual ~ValueFloatToRGB() = default;
|
||||
};
|
||||
|
||||
|
||||
@@ -74,22 +76,26 @@ class AppExport ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModel() = default;
|
||||
explicit ColorModel (std::size_t usCt) {
|
||||
explicit ColorModel(std::size_t usCt)
|
||||
{
|
||||
colors.resize(usCt);
|
||||
}
|
||||
ColorModel(const ColorModel&) = default;
|
||||
virtual ~ColorModel () = default;
|
||||
ColorModel& operator = (const ColorModel&) = default;
|
||||
std::size_t getCountColors() const {
|
||||
virtual ~ColorModel() = default;
|
||||
ColorModel& operator=(const ColorModel&) = default;
|
||||
std::size_t getCountColors() const
|
||||
{
|
||||
return colors.size();
|
||||
}
|
||||
std::vector<Color> colors;
|
||||
};
|
||||
|
||||
class AppExport ColorModelBlueGreenRed : public ColorModel
|
||||
class AppExport ColorModelBlueGreenRed: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelBlueGreenRed () : ColorModel(5) {
|
||||
ColorModelBlueGreenRed()
|
||||
: ColorModel(5)
|
||||
{
|
||||
colors[0] = Color(0, 0, 1);
|
||||
colors[1] = Color(0, 1, 1);
|
||||
colors[2] = Color(0, 1, 0);
|
||||
@@ -98,30 +104,36 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelBlueCyanGreen : public ColorModel
|
||||
class AppExport ColorModelBlueCyanGreen: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelBlueCyanGreen () : ColorModel(3) {
|
||||
ColorModelBlueCyanGreen()
|
||||
: ColorModel(3)
|
||||
{
|
||||
colors[0] = Color(0, 0, 1);
|
||||
colors[1] = Color(0, 1, 1);
|
||||
colors[2] = Color(0, 1, 0);
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelGreenYellowRed : public ColorModel
|
||||
class AppExport ColorModelGreenYellowRed: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelGreenYellowRed () : ColorModel(3) {
|
||||
ColorModelGreenYellowRed()
|
||||
: ColorModel(3)
|
||||
{
|
||||
colors[0] = Color(0, 1, 0);
|
||||
colors[1] = Color(1, 1, 0);
|
||||
colors[2] = Color(1, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelRedGreenBlue : public ColorModel
|
||||
class AppExport ColorModelRedGreenBlue: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelRedGreenBlue () : ColorModel(5) {
|
||||
ColorModelRedGreenBlue()
|
||||
: ColorModel(5)
|
||||
{
|
||||
colors[0] = Color(1, 0, 0);
|
||||
colors[1] = Color(1, 1, 0);
|
||||
colors[2] = Color(0, 1, 0);
|
||||
@@ -130,30 +142,36 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelGreenCyanBlue : public ColorModel
|
||||
class AppExport ColorModelGreenCyanBlue: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelGreenCyanBlue () : ColorModel(3) {
|
||||
ColorModelGreenCyanBlue()
|
||||
: ColorModel(3)
|
||||
{
|
||||
colors[0] = Color(0, 1, 0);
|
||||
colors[1] = Color(0, 1, 1);
|
||||
colors[2] = Color(0, 0, 1);
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelRedYellowGreen : public ColorModel
|
||||
class AppExport ColorModelRedYellowGreen: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelRedYellowGreen () : ColorModel(3) {
|
||||
ColorModelRedYellowGreen()
|
||||
: ColorModel(3)
|
||||
{
|
||||
colors[0] = Color(1, 0, 0);
|
||||
colors[1] = Color(1, 1, 0);
|
||||
colors[2] = Color(0, 1, 0);
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelBlueWhiteRed : public ColorModel
|
||||
class AppExport ColorModelBlueWhiteRed: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelBlueWhiteRed () : ColorModel(5) {
|
||||
ColorModelBlueWhiteRed()
|
||||
: ColorModel(5)
|
||||
{
|
||||
colors[0] = Color(0, 0, 1);
|
||||
colors[1] = Color(float(85.0 / 255), float(170.0 / 255), 1);
|
||||
colors[2] = Color(1, 1, 1);
|
||||
@@ -162,75 +180,91 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelBlueWhite : public ColorModel
|
||||
class AppExport ColorModelBlueWhite: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelBlueWhite () : ColorModel(3) {
|
||||
ColorModelBlueWhite()
|
||||
: ColorModel(3)
|
||||
{
|
||||
colors[0] = Color(0, 0, 1);
|
||||
colors[1] = Color(float(85.0 / 255), float(170.0 / 255), 1);
|
||||
colors[2] = Color(1, 1, 1);
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelWhiteRed : public ColorModel
|
||||
class AppExport ColorModelWhiteRed: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelWhiteRed () : ColorModel(3) {
|
||||
ColorModelWhiteRed()
|
||||
: ColorModel(3)
|
||||
{
|
||||
colors[0] = Color(1, 1, 1);
|
||||
colors[1] = Color(1, float(85.0 / 255), 0);
|
||||
colors[2] = Color(1, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelBlackWhite : public ColorModel
|
||||
class AppExport ColorModelBlackWhite: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelBlackWhite () : ColorModel(2) {
|
||||
ColorModelBlackWhite()
|
||||
: ColorModel(2)
|
||||
{
|
||||
colors[0] = Color(0, 0, 0);
|
||||
colors[1] = Color(1, 1, 1);
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelBlackGray : public ColorModel
|
||||
class AppExport ColorModelBlackGray: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelBlackGray () : ColorModel(2) {
|
||||
ColorModelBlackGray()
|
||||
: ColorModel(2)
|
||||
{
|
||||
colors[0] = Color(0.0f, 0.0f, 0.0f);
|
||||
colors[1] = Color(0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelGrayWhite : public ColorModel
|
||||
class AppExport ColorModelGrayWhite: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelGrayWhite () : ColorModel(2) {
|
||||
ColorModelGrayWhite()
|
||||
: ColorModel(2)
|
||||
{
|
||||
colors[0] = Color(0.5f, 0.5f, 0.5f);
|
||||
colors[1] = Color(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelWhiteBlack : public ColorModel
|
||||
class AppExport ColorModelWhiteBlack: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelWhiteBlack () : ColorModel(2) {
|
||||
ColorModelWhiteBlack()
|
||||
: ColorModel(2)
|
||||
{
|
||||
colors[0] = Color(1, 1, 1);
|
||||
colors[1] = Color(0, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelWhiteGray : public ColorModel
|
||||
class AppExport ColorModelWhiteGray: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelWhiteGray () : ColorModel(2) {
|
||||
ColorModelWhiteGray()
|
||||
: ColorModel(2)
|
||||
{
|
||||
colors[0] = Color(1.0f, 1.0f, 1.0f);
|
||||
colors[1] = Color(0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport ColorModelGrayBlack : public ColorModel
|
||||
class AppExport ColorModelGrayBlack: public ColorModel
|
||||
{
|
||||
public:
|
||||
ColorModelGrayBlack () : ColorModel(2) {
|
||||
ColorModelGrayBlack()
|
||||
: ColorModel(2)
|
||||
{
|
||||
colors[0] = Color(0.5f, 0.5f, 0.5f);
|
||||
colors[1] = Color(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
@@ -252,48 +286,59 @@ struct AppExport ColorModelPack
|
||||
class AppExport ColorField
|
||||
{
|
||||
public:
|
||||
ColorField ();
|
||||
ColorField (const ColorField &rclCF) = default;
|
||||
ColorField (const ColorModel &rclModel, float fMin, float fMax, std::size_t usCt);
|
||||
virtual ~ColorField () = default;
|
||||
ColorField();
|
||||
ColorField(const ColorField& rclCF) = default;
|
||||
ColorField(const ColorModel& rclModel, float fMin, float fMax, std::size_t usCt);
|
||||
virtual ~ColorField() = default;
|
||||
|
||||
ColorField& operator = (const ColorField &rclCF);
|
||||
ColorField& operator=(const ColorField& rclCF);
|
||||
|
||||
std::size_t getCountColors () const {
|
||||
std::size_t getCountColors() const
|
||||
{
|
||||
return ctColors;
|
||||
}
|
||||
void set (const ColorModel &rclModel, float fMin, float fMax, std::size_t usCt);
|
||||
void setCountColors (std::size_t usCt) {
|
||||
void set(const ColorModel& rclModel, float fMin, float fMax, std::size_t usCt);
|
||||
void setCountColors(std::size_t usCt)
|
||||
{
|
||||
set(colorModel, fMin, fMax, usCt);
|
||||
}
|
||||
void setRange (float fMin, float fMax) {
|
||||
void setRange(float fMin, float fMax)
|
||||
{
|
||||
set(colorModel, fMin, fMax, ctColors);
|
||||
}
|
||||
void getRange (float &rfMin, float &rfMax) {
|
||||
rfMin = fMin; rfMax = fMax;
|
||||
void getRange(float& rfMin, float& rfMax)
|
||||
{
|
||||
rfMin = fMin;
|
||||
rfMax = fMax;
|
||||
}
|
||||
std::size_t getMinColors () const {
|
||||
std::size_t getMinColors() const
|
||||
{
|
||||
return colorModel.getCountColors();
|
||||
}
|
||||
void setColorModel (const ColorModel &rclModel);
|
||||
const ColorModel& getColorModel () const {
|
||||
void setColorModel(const ColorModel& rclModel);
|
||||
const ColorModel& getColorModel() const
|
||||
{
|
||||
return colorModel;
|
||||
}
|
||||
void setDirect (std::size_t usInd, Color clCol) {
|
||||
void setDirect(std::size_t usInd, Color clCol)
|
||||
{
|
||||
colorField[usInd] = clCol;
|
||||
}
|
||||
float getMinValue () const {
|
||||
float getMinValue() const
|
||||
{
|
||||
return fMin;
|
||||
}
|
||||
float getMaxValue () const {
|
||||
float getMaxValue() const
|
||||
{
|
||||
return fMax;
|
||||
}
|
||||
|
||||
Color getColor (std::size_t usIndex) const {
|
||||
Color getColor(std::size_t usIndex) const
|
||||
{
|
||||
return colorField[usIndex];
|
||||
}
|
||||
inline Color getColor (float fVal) const;
|
||||
inline std::size_t getColorIndex (float fVal) const;
|
||||
inline Color getColor(float fVal) const;
|
||||
inline std::size_t getColorIndex(float fVal) const;
|
||||
|
||||
protected:
|
||||
ColorModel colorModel;
|
||||
@@ -302,32 +347,34 @@ protected:
|
||||
std::size_t ctColors;
|
||||
std::vector<Color> colorField;
|
||||
|
||||
void rebuild ();
|
||||
void interpolate (Color clCol1, std::size_t usPos1, Color clCol2, std::size_t usPos2);
|
||||
void rebuild();
|
||||
void interpolate(Color clCol1, std::size_t usPos1, Color clCol2, std::size_t usPos2);
|
||||
};
|
||||
|
||||
inline Color ColorField::getColor (float fVal) const
|
||||
inline Color ColorField::getColor(float fVal) const
|
||||
{
|
||||
// if the value is outside or at the border of the range
|
||||
std::size_t ct = colorModel.getCountColors() - 1;
|
||||
if ( fVal <= fMin )
|
||||
if (fVal <= fMin) {
|
||||
return colorModel.colors[0];
|
||||
else if ( fVal >= fMax )
|
||||
}
|
||||
else if (fVal >= fMax) {
|
||||
return colorModel.colors[ct];
|
||||
}
|
||||
|
||||
// get the color field position (with 0 < t < 1)
|
||||
float t = (fVal - fMin) / (fMax - fMin);
|
||||
Color col(1.0f, 1.0f, 1.0f); // white as default
|
||||
for (std::size_t i=0; i<ct; i++) {
|
||||
float r = (float)(i+1)/(float)ct;
|
||||
Color col(1.0f, 1.0f, 1.0f); // white as default
|
||||
for (std::size_t i = 0; i < ct; i++) {
|
||||
float r = (float)(i + 1) / (float)ct;
|
||||
if (t < r) {
|
||||
// calculate the exact position in the subrange
|
||||
float s = t * float(ct) - float(i);
|
||||
Color c1 = colorModel.colors[i];
|
||||
Color c2 = colorModel.colors[i+1];
|
||||
col.r = (1.0f-s) * c1.r + s * c2.r;
|
||||
col.g = (1.0f-s) * c1.g + s * c2.g;
|
||||
col.b = (1.0f-s) * c1.b + s * c2.b;
|
||||
Color c2 = colorModel.colors[i + 1];
|
||||
col.r = (1.0f - s) * c1.r + s * c2.r;
|
||||
col.g = (1.0f - s) * c1.g + s * c2.g;
|
||||
col.b = (1.0f - s) * c1.b + s * c2.b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -335,23 +382,24 @@ inline Color ColorField::getColor (float fVal) const
|
||||
return col;
|
||||
}
|
||||
|
||||
inline std::size_t ColorField::getColorIndex (float fVal) const
|
||||
inline std::size_t ColorField::getColorIndex(float fVal) const
|
||||
{
|
||||
return std::size_t(std::min<int>(std::max<int>(int(fConstant + fAscent * fVal), 0), int(ctColors - 1)));
|
||||
return std::size_t(
|
||||
std::min<int>(std::max<int>(int(fConstant + fAscent * fVal), 0), int(ctColors - 1)));
|
||||
}
|
||||
|
||||
struct AppExport ColorGradientProfile
|
||||
{
|
||||
ColorBarStyle tStyle{ColorBarStyle::FLOW};
|
||||
float fMin{};
|
||||
float fMax{};
|
||||
std::size_t ctColors{};
|
||||
std::size_t tColorModel{};
|
||||
VisibilityFlags visibility{Visibility::Default};
|
||||
ColorBarStyle tStyle {ColorBarStyle::FLOW};
|
||||
float fMin {};
|
||||
float fMax {};
|
||||
std::size_t ctColors {};
|
||||
std::size_t tColorModel {};
|
||||
VisibilityFlags visibility {Visibility::Default};
|
||||
|
||||
ColorGradientProfile();
|
||||
ColorGradientProfile (const ColorGradientProfile &) = default;
|
||||
ColorGradientProfile& operator = (const ColorGradientProfile &) = default;
|
||||
ColorGradientProfile(const ColorGradientProfile&) = default;
|
||||
ColorGradientProfile& operator=(const ColorGradientProfile&) = default;
|
||||
|
||||
bool isEqual(const ColorGradientProfile&) const;
|
||||
};
|
||||
@@ -359,184 +407,217 @@ struct AppExport ColorGradientProfile
|
||||
class AppExport ColorGradient
|
||||
{
|
||||
public:
|
||||
ColorGradient ();
|
||||
ColorGradient (float fMin, float fMax, std::size_t usCtColors, ColorBarStyle tS, VisibilityFlags fl = Visibility::Default);
|
||||
ColorGradient (const ColorGradient &) = default;
|
||||
ColorGradient& operator = (const ColorGradient &) = default;
|
||||
const ColorGradientProfile& getProfile() const {
|
||||
ColorGradient();
|
||||
ColorGradient(float fMin,
|
||||
float fMax,
|
||||
std::size_t usCtColors,
|
||||
ColorBarStyle tS,
|
||||
VisibilityFlags fl = Visibility::Default);
|
||||
ColorGradient(const ColorGradient&) = default;
|
||||
ColorGradient& operator=(const ColorGradient&) = default;
|
||||
const ColorGradientProfile& getProfile() const
|
||||
{
|
||||
return profile;
|
||||
}
|
||||
void setProfile(const ColorGradientProfile& pro);
|
||||
|
||||
void set (float fMin, float fMax, std::size_t usCt, ColorBarStyle tS, VisibilityFlags fl);
|
||||
void setRange (float fMin, float fMax) {
|
||||
void set(float fMin, float fMax, std::size_t usCt, ColorBarStyle tS, VisibilityFlags fl);
|
||||
void setRange(float fMin, float fMax)
|
||||
{
|
||||
set(fMin, fMax, profile.ctColors, profile.tStyle, profile.visibility);
|
||||
}
|
||||
void getRange (float &rfMin, float &rfMax) const {
|
||||
void getRange(float& rfMin, float& rfMax) const
|
||||
{
|
||||
rfMin = profile.fMin;
|
||||
rfMax = profile.fMax;
|
||||
}
|
||||
bool isOutOfRange(float fVal) const {
|
||||
bool isOutOfRange(float fVal) const
|
||||
{
|
||||
return ((fVal < profile.fMin) || (fVal > profile.fMax));
|
||||
}
|
||||
std::size_t getCountColors () const {
|
||||
std::size_t getCountColors() const
|
||||
{
|
||||
return profile.ctColors;
|
||||
}
|
||||
void setCountColors (std::size_t usCt) {
|
||||
void setCountColors(std::size_t usCt)
|
||||
{
|
||||
set(profile.fMin, profile.fMax, usCt, profile.tStyle, profile.visibility);
|
||||
}
|
||||
void setStyle (ColorBarStyle tS) {
|
||||
void setStyle(ColorBarStyle tS)
|
||||
{
|
||||
set(profile.fMin, profile.fMax, profile.ctColors, tS, profile.visibility);
|
||||
}
|
||||
std::size_t getMinColors () const;
|
||||
ColorBarStyle getStyle () const {
|
||||
std::size_t getMinColors() const;
|
||||
ColorBarStyle getStyle() const
|
||||
{
|
||||
return profile.tStyle;
|
||||
}
|
||||
void setOutsideGrayed (bool value) {
|
||||
void setOutsideGrayed(bool value)
|
||||
{
|
||||
profile.visibility.setFlag(Visibility::Grayed, value);
|
||||
}
|
||||
bool isOutsideGrayed () const {
|
||||
bool isOutsideGrayed() const
|
||||
{
|
||||
return profile.visibility.testFlag(Visibility::Grayed);
|
||||
}
|
||||
void setOutsideInvisible (bool value) {
|
||||
void setOutsideInvisible(bool value)
|
||||
{
|
||||
profile.visibility.setFlag(Visibility::Invisible, value);
|
||||
}
|
||||
bool isOutsideInvisible () const {
|
||||
bool isOutsideInvisible() const
|
||||
{
|
||||
return profile.visibility.testFlag(Visibility::Invisible);
|
||||
}
|
||||
void setColorModel (std::size_t tModel);
|
||||
std::size_t getColorModelType () const {
|
||||
void setColorModel(std::size_t tModel);
|
||||
std::size_t getColorModelType() const
|
||||
{
|
||||
return profile.tColorModel;
|
||||
}
|
||||
inline const ColorModel& getColorModel () const;
|
||||
inline const ColorModel& getColorModel() const;
|
||||
std::vector<std::string> getColorModelNames() const;
|
||||
float getMinValue () const {
|
||||
float getMinValue() const
|
||||
{
|
||||
return profile.fMin;
|
||||
}
|
||||
float getMaxValue () const {
|
||||
float getMaxValue() const
|
||||
{
|
||||
return profile.fMax;
|
||||
}
|
||||
|
||||
inline Color getColor (float fVal) const;
|
||||
inline std::size_t getColorIndex (float fVal) const;
|
||||
inline Color getColor(float fVal) const;
|
||||
inline std::size_t getColorIndex(float fVal) const;
|
||||
|
||||
private:
|
||||
inline Color _getColor (float fVal) const;
|
||||
inline Color _getColor(float fVal) const;
|
||||
|
||||
protected:
|
||||
void createStandardPacks();
|
||||
|
||||
protected:
|
||||
ColorGradientProfile profile;
|
||||
ColorField colorField1, colorField2;
|
||||
ColorField colorField1, colorField2;
|
||||
ColorModelPack currentModelPack;
|
||||
std::vector<ColorModelPack> modelPacks;
|
||||
|
||||
void rebuild ();
|
||||
void setColorModel ();
|
||||
void rebuild();
|
||||
void setColorModel();
|
||||
};
|
||||
|
||||
|
||||
class AppExport ColorLegend
|
||||
{
|
||||
public:
|
||||
ColorLegend ();
|
||||
ColorLegend (const ColorLegend &rclCL) = default;
|
||||
virtual ~ColorLegend () = default;
|
||||
ColorLegend();
|
||||
ColorLegend(const ColorLegend& rclCL) = default;
|
||||
virtual ~ColorLegend() = default;
|
||||
|
||||
ColorLegend& operator = (const ColorLegend &rclCL) = default;
|
||||
bool operator == (const ColorLegend &rclCL) const;
|
||||
bool operator != (const ColorLegend &rclCL) const {
|
||||
ColorLegend& operator=(const ColorLegend& rclCL) = default;
|
||||
bool operator==(const ColorLegend& rclCL) const;
|
||||
bool operator!=(const ColorLegend& rclCL) const
|
||||
{
|
||||
return !(*this == rclCL);
|
||||
}
|
||||
|
||||
void resize (std::size_t ulN);
|
||||
std::size_t addMin (const std::string &rclName);
|
||||
std::size_t addMax (const std::string &rclName);
|
||||
bool remove (std::size_t ulPos);
|
||||
void removeFirst ();
|
||||
void removeLast ();
|
||||
void resize(std::size_t ulN);
|
||||
std::size_t addMin(const std::string& rclName);
|
||||
std::size_t addMax(const std::string& rclName);
|
||||
bool remove(std::size_t ulPos);
|
||||
void removeFirst();
|
||||
void removeLast();
|
||||
|
||||
Color getColor (std::size_t ulPos) const;
|
||||
uint32_t getPackedColor (std::size_t ulPos) const;
|
||||
bool setColor (std::size_t ulPos, float ucRed, float ucGreen, float ucBlue);
|
||||
bool setColor (std::size_t ulPos, unsigned long ulColor);
|
||||
float getValue (std::size_t ulPos) const;
|
||||
bool setValue (std::size_t ulPos, float fVal);
|
||||
std::string getText (std::size_t ulPos) const;
|
||||
bool setText (std::size_t ulPos, const std::string &rclName);
|
||||
std::size_t hasNumberOfFields () const {
|
||||
Color getColor(std::size_t ulPos) const;
|
||||
uint32_t getPackedColor(std::size_t ulPos) const;
|
||||
bool setColor(std::size_t ulPos, float ucRed, float ucGreen, float ucBlue);
|
||||
bool setColor(std::size_t ulPos, unsigned long ulColor);
|
||||
float getValue(std::size_t ulPos) const;
|
||||
bool setValue(std::size_t ulPos, float fVal);
|
||||
std::string getText(std::size_t ulPos) const;
|
||||
bool setText(std::size_t ulPos, const std::string& rclName);
|
||||
std::size_t hasNumberOfFields() const
|
||||
{
|
||||
return colorFields.size();
|
||||
}
|
||||
void setOutsideGrayed (bool bOS) {
|
||||
void setOutsideGrayed(bool bOS)
|
||||
{
|
||||
outsideGrayed = bOS;
|
||||
}
|
||||
bool isOutsideGrayed () const {
|
||||
bool isOutsideGrayed() const
|
||||
{
|
||||
return outsideGrayed;
|
||||
}
|
||||
inline float getMinValue () const;
|
||||
inline float getMaxValue () const;
|
||||
inline float getMinValue() const;
|
||||
inline float getMaxValue() const;
|
||||
|
||||
inline Color getColor (float fVal) const;
|
||||
inline std::size_t getColorIndex (float fVal) const;
|
||||
inline Color getColor(float fVal) const;
|
||||
inline std::size_t getColorIndex(float fVal) const;
|
||||
|
||||
protected:
|
||||
std::deque<Color> colorFields;
|
||||
std::deque<std::string> names;
|
||||
std::deque<float> values;
|
||||
bool outsideGrayed{false};
|
||||
bool outsideGrayed {false};
|
||||
};
|
||||
|
||||
inline Color ColorLegend::getColor (float fVal) const
|
||||
inline Color ColorLegend::getColor(float fVal) const
|
||||
{
|
||||
std::deque<float>::const_iterator pI;
|
||||
for (pI = values.begin(); pI != values.end(); ++pI) {
|
||||
if (fVal < *pI)
|
||||
if (fVal < *pI) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (outsideGrayed) {
|
||||
if ((pI == values.begin()) || (pI == values.end()))
|
||||
if ((pI == values.begin()) || (pI == values.end())) {
|
||||
return Color(0.5f, 0.5f, 0.5f);
|
||||
else
|
||||
}
|
||||
else {
|
||||
return colorFields[pI - values.begin() - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (pI == values.begin())
|
||||
if (pI == values.begin()) {
|
||||
return *colorFields.begin();
|
||||
else if (pI == values.end())
|
||||
return *(colorFields.end()-1);
|
||||
else
|
||||
}
|
||||
else if (pI == values.end()) {
|
||||
return *(colorFields.end() - 1);
|
||||
}
|
||||
else {
|
||||
return colorFields[pI - values.begin() - 1];
|
||||
}
|
||||
}
|
||||
|
||||
inline std::size_t ColorLegend::getColorIndex (float fVal) const
|
||||
inline std::size_t ColorLegend::getColorIndex(float fVal) const
|
||||
{
|
||||
std::deque<float>::const_iterator pI;
|
||||
for (pI = values.begin(); pI != values.end(); ++pI) {
|
||||
if (fVal < *pI)
|
||||
if (fVal < *pI) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pI == values.begin())
|
||||
if (pI == values.begin()) {
|
||||
return 0;
|
||||
else if (pI == values.end())
|
||||
}
|
||||
else if (pI == values.end()) {
|
||||
return (std::size_t)(colorFields.size() - 1);
|
||||
else
|
||||
}
|
||||
else {
|
||||
return pI - values.begin() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline float ColorLegend::getMinValue () const
|
||||
inline float ColorLegend::getMinValue() const
|
||||
{
|
||||
return values.front();
|
||||
}
|
||||
|
||||
inline float ColorLegend::getMaxValue () const
|
||||
inline float ColorLegend::getMaxValue() const
|
||||
{
|
||||
return values.back();
|
||||
}
|
||||
|
||||
inline Color ColorGradient::getColor (float fVal) const
|
||||
inline Color ColorGradient::getColor(float fVal) const
|
||||
{
|
||||
Color color = _getColor(fVal);
|
||||
if (isOutsideInvisible()) {
|
||||
@@ -548,73 +629,78 @@ inline Color ColorGradient::getColor (float fVal) const
|
||||
return color;
|
||||
}
|
||||
|
||||
inline Color ColorGradient::_getColor (float fVal) const
|
||||
inline Color ColorGradient::_getColor(float fVal) const
|
||||
{
|
||||
if (isOutsideGrayed()) {
|
||||
if (isOutOfRange(fVal))
|
||||
if (isOutOfRange(fVal)) {
|
||||
return Color(0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
switch (profile.tStyle) {
|
||||
case ColorBarStyle::ZERO_BASED:
|
||||
{
|
||||
case ColorBarStyle::ZERO_BASED: {
|
||||
if ((profile.fMin < 0.0f) && (profile.fMax > 0.0f)) {
|
||||
if (fVal < 0.0f)
|
||||
if (fVal < 0.0f) {
|
||||
return colorField1.getColor(fVal);
|
||||
else
|
||||
}
|
||||
else {
|
||||
return colorField2.getColor(fVal);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return colorField1.getColor(fVal);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
case ColorBarStyle::FLOW:
|
||||
{
|
||||
default:
|
||||
case ColorBarStyle::FLOW: {
|
||||
return colorField1.getColor(fVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline std::size_t ColorGradient::getColorIndex (float fVal) const
|
||||
inline std::size_t ColorGradient::getColorIndex(float fVal) const
|
||||
{
|
||||
switch (profile.tStyle) {
|
||||
case ColorBarStyle::ZERO_BASED:
|
||||
{
|
||||
case ColorBarStyle::ZERO_BASED: {
|
||||
if ((profile.fMin < 0.0f) && (profile.fMax > 0.0f)) {
|
||||
if (fVal < 0.0f)
|
||||
if (fVal < 0.0f) {
|
||||
return colorField1.getColorIndex(fVal);
|
||||
else
|
||||
return std::size_t(colorField1.getCountColors() + colorField2.getColorIndex(fVal));
|
||||
}
|
||||
else {
|
||||
return std::size_t(colorField1.getCountColors()
|
||||
+ colorField2.getColorIndex(fVal));
|
||||
}
|
||||
}
|
||||
else {
|
||||
return colorField1.getColorIndex(fVal);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
case ColorBarStyle::FLOW:
|
||||
{
|
||||
default:
|
||||
case ColorBarStyle::FLOW: {
|
||||
return colorField1.getColorIndex(fVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline const ColorModel& ColorGradient::getColorModel () const
|
||||
inline const ColorModel& ColorGradient::getColorModel() const
|
||||
{
|
||||
if (profile.tStyle == ColorBarStyle::ZERO_BASED) {
|
||||
if (profile.fMax <= 0.0f)
|
||||
if (profile.fMax <= 0.0f) {
|
||||
return currentModelPack.bottomModel;
|
||||
else if ( profile.fMin >= 0.0f )
|
||||
}
|
||||
else if (profile.fMin >= 0.0f) {
|
||||
return currentModelPack.topModel;
|
||||
else
|
||||
}
|
||||
else {
|
||||
return currentModelPack.totalModel;
|
||||
}
|
||||
}
|
||||
|
||||
return currentModelPack.totalModel;
|
||||
}
|
||||
|
||||
} // namespace App
|
||||
} // namespace App
|
||||
|
||||
#endif // APP_COLORMODEL_H
|
||||
#endif // APP_COLORMODEL_H
|
||||
|
||||
+14
-12
@@ -184,20 +184,20 @@ bool ComplexGeoData::getCenterOfGravity(Base::Vector3d& unused) const
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string &ComplexGeoData::elementMapPrefix() {
|
||||
const std::string& ComplexGeoData::elementMapPrefix()
|
||||
{
|
||||
static std::string prefix(ELEMENT_MAP_PREFIX);
|
||||
return prefix;
|
||||
}
|
||||
|
||||
std::string ComplexGeoData::getElementMapVersion() const {
|
||||
std::string ComplexGeoData::getElementMapVersion() const
|
||||
{
|
||||
return "4";
|
||||
}
|
||||
|
||||
bool ComplexGeoData::checkElementMapVersion(const char * ver) const
|
||||
bool ComplexGeoData::checkElementMapVersion(const char* ver) const
|
||||
{
|
||||
return !boost::equals(ver, "3")
|
||||
&& !boost::equals(ver, "4")
|
||||
&& !boost::starts_with(ver, "3.");
|
||||
return !boost::equals(ver, "3") && !boost::equals(ver, "4") && !boost::starts_with(ver, "3.");
|
||||
}
|
||||
|
||||
size_t ComplexGeoData::getElementMapSize(bool flush) const
|
||||
@@ -301,8 +301,9 @@ ElementMapPtr ComplexGeoData::resetElementMap(ElementMapPtr elementMap)
|
||||
_elementMap.swap(elementMap);
|
||||
// We expect that if the ComplexGeoData ( TopoShape ) has a hasher, then its elementMap will
|
||||
// have the same one. Make sure that happens.
|
||||
if ( _elementMap && ! _elementMap->hasher )
|
||||
if (_elementMap && !_elementMap->hasher) {
|
||||
_elementMap->hasher = Hasher;
|
||||
}
|
||||
return elementMap;
|
||||
}
|
||||
|
||||
@@ -329,7 +330,6 @@ ElementMapPtr ComplexGeoData::ensureElementMap(bool flush)
|
||||
resetElementMap(std::make_shared<Data::ElementMap>());
|
||||
}
|
||||
return elementMap(flush);
|
||||
|
||||
}
|
||||
|
||||
void ComplexGeoData::flushElementMap() const
|
||||
@@ -656,12 +656,13 @@ unsigned int ComplexGeoData::getMemSize() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<IndexedName> ComplexGeoData::getHigherElements(const char *, bool) const
|
||||
std::vector<IndexedName> ComplexGeoData::getHigherElements(const char*, bool) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
void ComplexGeoData::setMappedChildElements(const std::vector<Data::ElementMap::MappedChildElements> & children)
|
||||
void ComplexGeoData::setMappedChildElements(
|
||||
const std::vector<Data::ElementMap::MappedChildElements>& children)
|
||||
{
|
||||
// DO NOT reset element map if there is one. Because we allow mixing child
|
||||
// mapping and normal mapping
|
||||
@@ -690,8 +691,9 @@ void ComplexGeoData::beforeSave() const
|
||||
void ComplexGeoData::hashChildMaps()
|
||||
{
|
||||
flushElementMap();
|
||||
if (_elementMap)
|
||||
if (_elementMap) {
|
||||
_elementMap->hashChildMaps(Tag);
|
||||
}
|
||||
}
|
||||
|
||||
bool ComplexGeoData::hasChildElementMap() const
|
||||
@@ -704,7 +706,7 @@ void ComplexGeoData::dumpElementMap(std::ostream& stream) const
|
||||
{
|
||||
auto map = getElementMap();
|
||||
std::sort(map.begin(), map.end());
|
||||
for ( auto& element : map ) {
|
||||
for (auto& element : map) {
|
||||
stream << element.index << " : " << element.name << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
+123
-90
@@ -37,7 +37,7 @@
|
||||
#include "StringHasher.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
# include <cstdint>
|
||||
#include <cstdint>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -45,16 +45,18 @@ namespace Base
|
||||
{
|
||||
class Placement;
|
||||
class Rotation;
|
||||
template <class _Precision> class BoundBox3;// NOLINT
|
||||
template<class _Precision>
|
||||
class BoundBox3; // NOLINT
|
||||
using BoundBox3d = BoundBox3<double>;
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
namespace Data
|
||||
{
|
||||
|
||||
//struct MappedChildElements;
|
||||
// struct MappedChildElements;
|
||||
/// Option for App::GeoFeature::searchElementCache()
|
||||
enum class SearchOption {
|
||||
enum class SearchOption
|
||||
{
|
||||
/// Whether to compare shape geometry
|
||||
CheckGeometry = 1,
|
||||
SingleResult = 2,
|
||||
@@ -67,11 +69,11 @@ typedef Base::Flags<SearchOption> SearchOptions;
|
||||
*/
|
||||
class AppExport Segment: public Base::BaseClass
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();// NOLINT
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE(); // NOLINT
|
||||
|
||||
public:
|
||||
~Segment() override = default;
|
||||
virtual std::string getName() const=0;
|
||||
virtual std::string getName() const = 0;
|
||||
};
|
||||
|
||||
enum ElementMapResetPolicy
|
||||
@@ -84,12 +86,22 @@ enum ElementMapResetPolicy
|
||||
*/
|
||||
class AppExport ComplexGeoData: public Base::Persistence, public Base::Handled
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();// NOLINT
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE(); // NOLINT
|
||||
|
||||
public:
|
||||
struct Line {uint32_t I1; uint32_t I2;};
|
||||
struct Facet {uint32_t I1; uint32_t I2; uint32_t I3;};
|
||||
struct Domain {
|
||||
struct Line
|
||||
{
|
||||
uint32_t I1;
|
||||
uint32_t I2;
|
||||
};
|
||||
struct Facet
|
||||
{
|
||||
uint32_t I1;
|
||||
uint32_t I2;
|
||||
uint32_t I3;
|
||||
};
|
||||
struct Domain
|
||||
{
|
||||
std::vector<Base::Vector3d> points;
|
||||
std::vector<Facet> facets;
|
||||
};
|
||||
@@ -105,26 +117,24 @@ public:
|
||||
* List of different sub-element types
|
||||
* its NOT a list of the sub-elements itself
|
||||
*/
|
||||
virtual std::vector<const char*> getElementTypes() const=0;
|
||||
virtual unsigned long countSubElements(const char* Type) const=0;
|
||||
virtual std::vector<const char*> getElementTypes() const = 0;
|
||||
virtual unsigned long countSubElements(const char* Type) const = 0;
|
||||
/// Returns a generic element type and index. The determined element type isn't
|
||||
/// necessarily supported by this geometry.
|
||||
static std::pair<std::string, unsigned long> getTypeAndIndex(const char* Name);
|
||||
/// get the sub-element by type and number
|
||||
virtual Segment* getSubElement(const char* Type, unsigned long) const=0;
|
||||
virtual Segment* getSubElement(const char* Type, unsigned long) const = 0;
|
||||
/// get sub-element by combined name
|
||||
virtual Segment* getSubElementByName(const char* Name) const;
|
||||
/** Get lines from segment */
|
||||
virtual void getLinesFromSubElement(
|
||||
const Segment*,
|
||||
std::vector<Base::Vector3d> &Points,
|
||||
std::vector<Line> &lines) const;
|
||||
virtual void getLinesFromSubElement(const Segment*,
|
||||
std::vector<Base::Vector3d>& Points,
|
||||
std::vector<Line>& lines) const;
|
||||
/** Get faces from segment */
|
||||
virtual void getFacesFromSubElement(
|
||||
const Segment*,
|
||||
std::vector<Base::Vector3d> &Points,
|
||||
std::vector<Base::Vector3d> &PointNormals,
|
||||
std::vector<Facet> &faces) const;
|
||||
virtual void getFacesFromSubElement(const Segment*,
|
||||
std::vector<Base::Vector3d>& Points,
|
||||
std::vector<Base::Vector3d>& PointNormals,
|
||||
std::vector<Facet>& faces) const;
|
||||
//@}
|
||||
|
||||
/** @name Placement control */
|
||||
@@ -147,7 +157,7 @@ public:
|
||||
* This method has to be handled by the child classes.
|
||||
* the actual placement and matrix is not part of this class.
|
||||
*/
|
||||
virtual void setTransform(const Base::Matrix4D& rclTrf)=0;
|
||||
virtual void setTransform(const Base::Matrix4D& rclTrf) = 0;
|
||||
/** Return the current matrix
|
||||
* This method has to be handled by the child classes.
|
||||
* the actual placement and matrix is not part of this class.
|
||||
@@ -158,7 +168,7 @@ public:
|
||||
/** @name Modification */
|
||||
//@{
|
||||
/// Applies a transformation on the real geometric data type
|
||||
virtual void transformGeometry(const Base::Matrix4D &rclMat) = 0;
|
||||
virtual void transformGeometry(const Base::Matrix4D& rclMat) = 0;
|
||||
//@}
|
||||
|
||||
/** @name Getting basic geometric entities */
|
||||
@@ -166,21 +176,25 @@ public:
|
||||
/// Get the standard accuracy to be used with getPoints, getLines or getFaces
|
||||
virtual double getAccuracy() const;
|
||||
/// Get the bound box
|
||||
virtual Base::BoundBox3d getBoundBox() const=0;
|
||||
virtual Base::BoundBox3d getBoundBox() const = 0;
|
||||
/** Get point from line object intersection */
|
||||
virtual Base::Vector3d getPointFromLineIntersection(
|
||||
const Base::Vector3f& base,
|
||||
const Base::Vector3f& dir) const;
|
||||
virtual Base::Vector3d getPointFromLineIntersection(const Base::Vector3f& base,
|
||||
const Base::Vector3f& dir) const;
|
||||
/** Get points from object with given accuracy */
|
||||
virtual void getPoints(std::vector<Base::Vector3d> &Points,
|
||||
std::vector<Base::Vector3d> &Normals,
|
||||
double Accuracy, uint16_t flags=0) const;
|
||||
virtual void getPoints(std::vector<Base::Vector3d>& Points,
|
||||
std::vector<Base::Vector3d>& Normals,
|
||||
double Accuracy,
|
||||
uint16_t flags = 0) const;
|
||||
/** Get lines from object with given accuracy */
|
||||
virtual void getLines(std::vector<Base::Vector3d> &Points,std::vector<Line> &lines,
|
||||
double Accuracy, uint16_t flags=0) const;
|
||||
virtual void getLines(std::vector<Base::Vector3d>& Points,
|
||||
std::vector<Line>& lines,
|
||||
double Accuracy,
|
||||
uint16_t flags = 0) const;
|
||||
/** Get faces from object with given accuracy */
|
||||
virtual void getFaces(std::vector<Base::Vector3d> &Points,std::vector<Facet> &faces,
|
||||
double Accuracy, uint16_t flags=0) const;
|
||||
virtual void getFaces(std::vector<Base::Vector3d>& Points,
|
||||
std::vector<Facet>& faces,
|
||||
double Accuracy,
|
||||
uint16_t flags = 0) const;
|
||||
/** Get the center of gravity
|
||||
* If this method is implemented then true is returned and the center of gravity.
|
||||
* The default implementation only returns false.
|
||||
@@ -188,7 +202,7 @@ public:
|
||||
virtual bool getCenterOfGravity(Base::Vector3d& center) const;
|
||||
//@}
|
||||
|
||||
static const std::string &elementMapPrefix();
|
||||
static const std::string& elementMapPrefix();
|
||||
|
||||
/** @name Element name mapping */
|
||||
//@{
|
||||
@@ -200,8 +214,7 @@ public:
|
||||
*
|
||||
* @return Returns an indexed name.
|
||||
*/
|
||||
IndexedName getIndexedName(const MappedName & name,
|
||||
ElementIDRefs *sid = nullptr) const;
|
||||
IndexedName getIndexedName(const MappedName& name, ElementIDRefs* sid = nullptr) const;
|
||||
|
||||
/** Get element mapped name
|
||||
*
|
||||
@@ -212,9 +225,9 @@ public:
|
||||
* @param sid: optional output of and App::StringID involved forming this mapped name
|
||||
* @return Returns the mapped name.
|
||||
*/
|
||||
MappedName getMappedName(const IndexedName & element,
|
||||
MappedName getMappedName(const IndexedName& element,
|
||||
bool allowUnmapped = false,
|
||||
ElementIDRefs *sid = nullptr) const;
|
||||
ElementIDRefs* sid = nullptr) const;
|
||||
|
||||
/** Return a pair of indexed name and mapped name
|
||||
*
|
||||
@@ -233,9 +246,8 @@ public:
|
||||
* it will be treated as indexed name. Or else, it will be treated as
|
||||
* mapped name.
|
||||
*/
|
||||
MappedElement getElementName(const char * name,
|
||||
ElementIDRefs *sid = nullptr,
|
||||
bool copy = false) const;
|
||||
MappedElement
|
||||
getElementName(const char* name, ElementIDRefs* sid = nullptr, bool copy = false) const;
|
||||
|
||||
/** Add a sub-element name mapping.
|
||||
*
|
||||
@@ -259,11 +271,13 @@ public:
|
||||
const MappedName& name,
|
||||
long masterTag,
|
||||
const ElementIDRefs* sid = nullptr,
|
||||
bool overwrite = false) {
|
||||
return _elementMap -> setElementName(element, name, masterTag, sid, overwrite);
|
||||
bool overwrite = false)
|
||||
{
|
||||
return _elementMap->setElementName(element, name, masterTag, sid, overwrite);
|
||||
}
|
||||
|
||||
bool hasElementMap() {
|
||||
bool hasElementMap()
|
||||
{
|
||||
return _elementMap != nullptr;
|
||||
}
|
||||
|
||||
@@ -276,8 +290,8 @@ public:
|
||||
* @return a list of mapped names of the give element along with their
|
||||
* associated string ID references
|
||||
*/
|
||||
std::vector<std::pair<MappedName, ElementIDRefs> >
|
||||
getElementMappedNames(const IndexedName & element, bool needUnmapped=false) const;
|
||||
std::vector<std::pair<MappedName, ElementIDRefs>>
|
||||
getElementMappedNames(const IndexedName& element, bool needUnmapped = false) const;
|
||||
|
||||
/// Hash the child element map postfixes to shorten element name from hierarchical maps
|
||||
void hashChildMaps();
|
||||
@@ -286,29 +300,31 @@ public:
|
||||
bool hasChildElementMap() const;
|
||||
|
||||
/// Append the Tag (if and only if it is non zero) into the element map
|
||||
virtual void reTagElementMap(long tag,
|
||||
App::StringHasherRef hasher,
|
||||
const char *postfix=nullptr) {
|
||||
virtual void
|
||||
reTagElementMap(long tag, App::StringHasherRef hasher, const char* postfix = nullptr)
|
||||
{
|
||||
(void)tag;
|
||||
(void)hasher;
|
||||
(void)postfix;
|
||||
}
|
||||
|
||||
// NOTE: getElementHistory is now in ElementMap
|
||||
long getElementHistory(const MappedName & name,
|
||||
MappedName *original=nullptr, std::vector<MappedName> *history=nullptr) const {
|
||||
if ( _elementMap != nullptr ) {
|
||||
long getElementHistory(const MappedName& name,
|
||||
MappedName* original = nullptr,
|
||||
std::vector<MappedName>* history = nullptr) const
|
||||
{
|
||||
if (_elementMap != nullptr) {
|
||||
return _elementMap->getElementHistory(name, Tag, original, history);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
void setMappedChildElements(const std::vector<Data::ElementMap::MappedChildElements> & children);
|
||||
void setMappedChildElements(const std::vector<Data::ElementMap::MappedChildElements>& children);
|
||||
std::vector<Data::ElementMap::MappedChildElements> getMappedChildElements() const;
|
||||
|
||||
char elementType(const Data::MappedName &) const;
|
||||
char elementType(const Data::IndexedName &) const;
|
||||
char elementType(const char *name) const;
|
||||
char elementType(const Data::MappedName&) const;
|
||||
char elementType(const Data::IndexedName&) const;
|
||||
char elementType(const char* name) const;
|
||||
|
||||
/** Reset/swap the element map
|
||||
*
|
||||
@@ -322,19 +338,19 @@ public:
|
||||
std::vector<MappedElement> getElementMap() const;
|
||||
|
||||
/// Set the entire element map
|
||||
void setElementMap(const std::vector<MappedElement> &elements);
|
||||
void setElementMap(const std::vector<MappedElement>& elements);
|
||||
|
||||
/// Get the current element map size
|
||||
size_t getElementMapSize(bool flush=true) const;
|
||||
size_t getElementMapSize(bool flush = true) const;
|
||||
|
||||
/// Return the higher level element names of the given element
|
||||
virtual std::vector<IndexedName> getHigherElements(const char *name, bool silent=false) const;
|
||||
virtual std::vector<IndexedName> getHigherElements(const char* name, bool silent = false) const;
|
||||
|
||||
/// Return the current element map version
|
||||
virtual std::string getElementMapVersion() const;
|
||||
|
||||
/// Return true to signal element map version change
|
||||
virtual bool checkElementMapVersion(const char * ver) const;
|
||||
virtual bool checkElementMapVersion(const char* ver) const;
|
||||
|
||||
/// Check if the given sub-name only contains an element name
|
||||
static bool isElementName(const char* subName)
|
||||
@@ -359,15 +375,21 @@ public:
|
||||
|
||||
/** @name Save/restore */
|
||||
//@{
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void SaveDocFile(Base::Writer &writer) const override;
|
||||
void RestoreDocFile(Base::Reader &reader) override;
|
||||
unsigned int getMemSize () const override;
|
||||
void setPersistenceFileName(const char *name) const;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
void SaveDocFile(Base::Writer& writer) const override;
|
||||
void RestoreDocFile(Base::Reader& reader) override;
|
||||
unsigned int getMemSize() const override;
|
||||
void setPersistenceFileName(const char* name) const;
|
||||
virtual void beforeSave() const;
|
||||
bool isRestoreFailed() const { return _restoreFailed; }
|
||||
void resetRestoreFailure() const { _restoreFailed = true; }
|
||||
bool isRestoreFailed() const
|
||||
{
|
||||
return _restoreFailed;
|
||||
}
|
||||
void resetRestoreFailure() const
|
||||
{
|
||||
_restoreFailed = true;
|
||||
}
|
||||
//@}
|
||||
|
||||
/**
|
||||
@@ -382,51 +404,60 @@ public:
|
||||
const std::string dumpElementMap() const;
|
||||
|
||||
protected:
|
||||
|
||||
/// from local to outside
|
||||
inline Base::Vector3d transformPointToOutside(const Base::Vector3f& vec) const
|
||||
{
|
||||
// clang-format off
|
||||
return getTransform() * Base::Vector3d(static_cast<double>(vec.x),
|
||||
static_cast<double>(vec.y),
|
||||
static_cast<double>(vec.z));
|
||||
// clang-format on
|
||||
}
|
||||
/// from local to outside
|
||||
template<typename Vec>
|
||||
inline std::vector<Base::Vector3d> transformPointsToOutside(const std::vector<Vec>& input) const
|
||||
{
|
||||
// clang-format off
|
||||
std::vector<Base::Vector3d> output;
|
||||
output.reserve(input.size());
|
||||
Base::Matrix4D mat(getTransform());
|
||||
std::transform(input.cbegin(), input.cend(), std::back_inserter(output), [&mat](const Vec& vec) {
|
||||
return mat * Base::Vector3d(static_cast<double>(vec.x),
|
||||
static_cast<double>(vec.y),
|
||||
static_cast<double>(vec.z));
|
||||
});
|
||||
std::transform(input.cbegin(), input.cend(), std::back_inserter(output),
|
||||
[&mat](const Vec& vec) {
|
||||
return mat * Base::Vector3d(static_cast<double>(vec.x),
|
||||
static_cast<double>(vec.y),
|
||||
static_cast<double>(vec.z));
|
||||
});
|
||||
|
||||
return output;
|
||||
// clang-format on
|
||||
}
|
||||
inline Base::Vector3d transformVectorToOutside(const Base::Vector3f& vec) const
|
||||
{
|
||||
// clang-format off
|
||||
Base::Matrix4D mat(getTransform());
|
||||
mat.setCol(3, Base::Vector3d());
|
||||
return mat * Base::Vector3d(static_cast<double>(vec.x),
|
||||
static_cast<double>(vec.y),
|
||||
static_cast<double>(vec.z));
|
||||
static_cast<double>(vec.y),
|
||||
static_cast<double>(vec.z));
|
||||
// clang-format on
|
||||
}
|
||||
template<typename Vec>
|
||||
std::vector<Base::Vector3d> transformVectorsToOutside(const std::vector<Vec>& input) const
|
||||
{
|
||||
// clang-format off
|
||||
std::vector<Base::Vector3d> output;
|
||||
output.reserve(input.size());
|
||||
Base::Matrix4D mat(getTransform());
|
||||
mat.setCol(3, Base::Vector3d());
|
||||
std::transform(input.cbegin(), input.cend(), std::back_inserter(output), [&mat](const Vec& vec) {
|
||||
return mat * Base::Vector3d(static_cast<double>(vec.x),
|
||||
static_cast<double>(vec.y),
|
||||
static_cast<double>(vec.z));
|
||||
});
|
||||
std::transform(input.cbegin(), input.cend(), std::back_inserter(output),
|
||||
[&mat](const Vec& vec) {
|
||||
return mat * Base::Vector3d(static_cast<double>(vec.x),
|
||||
static_cast<double>(vec.y),
|
||||
static_cast<double>(vec.z));
|
||||
});
|
||||
|
||||
return output;
|
||||
// clang-format on
|
||||
}
|
||||
/// from local to inside
|
||||
inline Base::Vector3f transformPointToInside(const Base::Vector3d& vec) const
|
||||
@@ -438,23 +469,25 @@ protected:
|
||||
static_cast<float>(tmp.y),
|
||||
static_cast<float>(tmp.z));
|
||||
}
|
||||
|
||||
public:
|
||||
mutable long Tag{0};
|
||||
mutable long Tag {0};
|
||||
|
||||
/// String hasher for element name shortening
|
||||
mutable App::StringHasherRef Hasher;
|
||||
|
||||
protected:
|
||||
|
||||
void restoreStream(std::istream & stream, std::size_t count);
|
||||
void restoreStream(std::istream& stream, std::size_t count);
|
||||
void readElements(Base::XMLReader& reader, size_t count);
|
||||
|
||||
/// from local to outside
|
||||
inline Base::Vector3d transformToOutside(const Base::Vector3f& vec) const
|
||||
{
|
||||
// clang-format off
|
||||
return getTransform() * Base::Vector3d(static_cast<double>(vec.x),
|
||||
static_cast<double>(vec.y),
|
||||
static_cast<double>(vec.z));
|
||||
// clang-format on
|
||||
}
|
||||
/// from local to inside
|
||||
inline Base::Vector3f transformToInside(const Base::Vector3d& vec) const
|
||||
@@ -468,8 +501,8 @@ protected:
|
||||
}
|
||||
|
||||
protected:
|
||||
ElementMapPtr elementMap(bool flush=true) const;
|
||||
ElementMapPtr ensureElementMap(bool flush=true);
|
||||
ElementMapPtr elementMap(bool flush = true) const;
|
||||
ElementMapPtr ensureElementMap(bool flush = true);
|
||||
|
||||
private:
|
||||
ElementMapPtr _elementMap;
|
||||
@@ -479,7 +512,7 @@ protected:
|
||||
mutable bool _restoreFailed = false;
|
||||
};
|
||||
|
||||
} //namespace App
|
||||
} // namespace Data
|
||||
|
||||
ENABLE_BITMASK_OPERATORS(Data::SearchOption)
|
||||
#endif
|
||||
|
||||
+1285
-892
File diff suppressed because it is too large
Load Diff
+183
-151
@@ -37,33 +37,32 @@
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
|
||||
namespace Base {
|
||||
class Writer;
|
||||
}
|
||||
|
||||
namespace App
|
||||
namespace Base
|
||||
{
|
||||
class TransactionalObject;
|
||||
class DocumentObject;
|
||||
class DocumentObjectExecReturn;
|
||||
class Document;
|
||||
class DocumentPy; // the python document class
|
||||
class Application;
|
||||
class Transaction;
|
||||
class StringHasher;
|
||||
using StringHasherRef = Base::Reference<StringHasher>;
|
||||
class Writer;
|
||||
}
|
||||
|
||||
namespace App
|
||||
{
|
||||
class TransactionalObject;
|
||||
class DocumentObject;
|
||||
class DocumentObjectExecReturn;
|
||||
class Document;
|
||||
class DocumentPy;
|
||||
class Application;
|
||||
class Transaction;
|
||||
class StringHasher;
|
||||
using StringHasherRef = Base::Reference<StringHasher>;
|
||||
|
||||
/// The document class
|
||||
class AppExport Document : public App::PropertyContainer
|
||||
class AppExport Document: public App::PropertyContainer
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(App::Document);
|
||||
|
||||
public:
|
||||
enum Status {
|
||||
// clang-format off
|
||||
enum Status
|
||||
{
|
||||
SkipRecompute = 0,
|
||||
KeepTrailingDigits = 1,
|
||||
Closable = 2,
|
||||
@@ -72,14 +71,16 @@ public:
|
||||
PartialRestore = 5,
|
||||
Importing = 6,
|
||||
PartialDoc = 7,
|
||||
AllowPartialRecompute = 8, // allow recomputing editing object if SkipRecompute is set
|
||||
TempDoc = 9, // Mark as temporary document without prompt for save
|
||||
AllowPartialRecompute = 8, // allow recomputing editing object if SkipRecompute is set
|
||||
TempDoc = 9, // Mark as temporary document without prompt for save
|
||||
RestoreError = 10,
|
||||
LinkStampChanged = 11, // Indicates during restore time if any linked document's time stamp has changed
|
||||
IgnoreErrorOnRecompute = 12, // Don't report errors if the recompute failed
|
||||
RecomputeOnRestore = 13, // Mark pending recompute on restore for migration purposes
|
||||
LinkStampChanged = 11, // Indicates during restore time if any linked document's time stamp has changed
|
||||
IgnoreErrorOnRecompute = 12, // Don't report errors if the recompute failed
|
||||
RecomputeOnRestore = 13, // Mark pending recompute on restore for migration purposes
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// NOLINTBEGIN
|
||||
/** @name Properties */
|
||||
//@{
|
||||
/// holds the long name of the document (utf-8 coded)
|
||||
@@ -124,67 +125,66 @@ public:
|
||||
|
||||
/** @name Signals of the document */
|
||||
//@{
|
||||
// clang-format off
|
||||
/// signal before changing an doc property
|
||||
boost::signals2::signal<void (const App::Document&, const App::Property&)> signalBeforeChange;
|
||||
boost::signals2::signal<void(const App::Document&, const App::Property&)> signalBeforeChange;
|
||||
/// signal on changed doc property
|
||||
boost::signals2::signal<void (const App::Document&, const App::Property&)> signalChanged;
|
||||
boost::signals2::signal<void(const App::Document&, const App::Property&)> signalChanged;
|
||||
/// signal on new Object
|
||||
boost::signals2::signal<void (const App::DocumentObject&)> signalNewObject;
|
||||
//boost::signals2::signal<void (const App::DocumentObject&)> m_sig;
|
||||
boost::signals2::signal<void(const App::DocumentObject&)> signalNewObject;
|
||||
/// signal on deleted Object
|
||||
boost::signals2::signal<void (const App::DocumentObject&)> signalDeletedObject;
|
||||
boost::signals2::signal<void(const App::DocumentObject&)> signalDeletedObject;
|
||||
/// signal before changing an Object
|
||||
boost::signals2::signal<void (const App::DocumentObject&, const App::Property&)> signalBeforeChangeObject;
|
||||
boost::signals2::signal<void(const App::DocumentObject&, const App::Property&)> signalBeforeChangeObject;
|
||||
/// signal on changed Object
|
||||
boost::signals2::signal<void (const App::DocumentObject&, const App::Property&)> signalChangedObject;
|
||||
boost::signals2::signal<void(const App::DocumentObject&, const App::Property&)> signalChangedObject;
|
||||
/// signal on manually called DocumentObject::touch()
|
||||
boost::signals2::signal<void (const App::DocumentObject&)> signalTouchedObject;
|
||||
boost::signals2::signal<void(const App::DocumentObject&)> signalTouchedObject;
|
||||
/// signal on relabeled Object
|
||||
boost::signals2::signal<void (const App::DocumentObject&)> signalRelabelObject;
|
||||
boost::signals2::signal<void(const App::DocumentObject&)> signalRelabelObject;
|
||||
/// signal on activated Object
|
||||
boost::signals2::signal<void (const App::DocumentObject&)> signalActivatedObject;
|
||||
boost::signals2::signal<void(const App::DocumentObject&)> signalActivatedObject;
|
||||
/// signal on created object
|
||||
boost::signals2::signal<void (const App::DocumentObject&, Transaction*)> signalTransactionAppend;
|
||||
boost::signals2::signal<void(const App::DocumentObject&, Transaction*)> signalTransactionAppend;
|
||||
/// signal on removed object
|
||||
boost::signals2::signal<void (const App::DocumentObject&, Transaction*)> signalTransactionRemove;
|
||||
boost::signals2::signal<void(const App::DocumentObject&, Transaction*)> signalTransactionRemove;
|
||||
/// signal on undo
|
||||
boost::signals2::signal<void (const App::Document&)> signalUndo;
|
||||
boost::signals2::signal<void(const App::Document&)> signalUndo;
|
||||
/// signal on redo
|
||||
boost::signals2::signal<void (const App::Document&)> signalRedo;
|
||||
boost::signals2::signal<void(const App::Document&)> signalRedo;
|
||||
/** signal on load/save document
|
||||
* this signal is given when the document gets streamed.
|
||||
* you can use this hook to write additional information in
|
||||
* the file (like the Gui::Document does).
|
||||
*/
|
||||
boost::signals2::signal<void (Base::Writer &)> signalSaveDocument;
|
||||
boost::signals2::signal<void (Base::XMLReader&)> signalRestoreDocument;
|
||||
boost::signals2::signal<void (const std::vector<App::DocumentObject*>&,
|
||||
Base::Writer &)> signalExportObjects;
|
||||
boost::signals2::signal<void (const std::vector<App::DocumentObject*>&,
|
||||
Base::Writer &)> signalExportViewObjects;
|
||||
boost::signals2::signal<void (const std::vector<App::DocumentObject*>&,
|
||||
Base::XMLReader&)> signalImportObjects;
|
||||
boost::signals2::signal<void (const std::vector<App::DocumentObject*>&, Base::Reader&,
|
||||
const std::map<std::string, std::string>&)> signalImportViewObjects;
|
||||
boost::signals2::signal<void (const std::vector<App::DocumentObject*>&)> signalFinishImportObjects;
|
||||
//signal starting a save action to a file
|
||||
boost::signals2::signal<void (const App::Document&, const std::string&)> signalStartSave;
|
||||
//signal finishing a save action to a file
|
||||
boost::signals2::signal<void (const App::Document&, const std::string&)> signalFinishSave;
|
||||
boost::signals2::signal<void (const App::Document&)> signalBeforeRecompute;
|
||||
boost::signals2::signal<void (const App::Document&, const std::vector<App::DocumentObject*>&)> signalRecomputed;
|
||||
boost::signals2::signal<void (const App::DocumentObject&)> signalRecomputedObject;
|
||||
//signal a new opened transaction
|
||||
boost::signals2::signal<void (const App::Document&, std::string)> signalOpenTransaction;
|
||||
boost::signals2::signal<void(Base::Writer&)> signalSaveDocument;
|
||||
boost::signals2::signal<void(Base::XMLReader&)> signalRestoreDocument;
|
||||
boost::signals2::signal<void(const std::vector<App::DocumentObject*>&, Base::Writer&)> signalExportObjects;
|
||||
boost::signals2::signal<void(const std::vector<App::DocumentObject*>&, Base::Writer&)> signalExportViewObjects;
|
||||
boost::signals2::signal<void(const std::vector<App::DocumentObject*>&, Base::XMLReader&)> signalImportObjects;
|
||||
boost::signals2::signal<void(const std::vector<App::DocumentObject*>&, Base::Reader&,
|
||||
const std::map<std::string, std::string>&)> signalImportViewObjects;
|
||||
boost::signals2::signal<void(const std::vector<App::DocumentObject*>&)> signalFinishImportObjects;
|
||||
// signal starting a save action to a file
|
||||
boost::signals2::signal<void(const App::Document&, const std::string&)> signalStartSave;
|
||||
// signal finishing a save action to a file
|
||||
boost::signals2::signal<void(const App::Document&, const std::string&)> signalFinishSave;
|
||||
boost::signals2::signal<void(const App::Document&)> signalBeforeRecompute;
|
||||
boost::signals2::signal<void(const App::Document&, const std::vector<App::DocumentObject*>&)> signalRecomputed;
|
||||
boost::signals2::signal<void(const App::DocumentObject&)> signalRecomputedObject;
|
||||
// signal a new opened transaction
|
||||
boost::signals2::signal<void(const App::Document&, std::string)> signalOpenTransaction;
|
||||
// signal a committed transaction
|
||||
boost::signals2::signal<void (const App::Document&)> signalCommitTransaction;
|
||||
boost::signals2::signal<void(const App::Document&)> signalCommitTransaction;
|
||||
// signal an aborted transaction
|
||||
boost::signals2::signal<void (const App::Document&)> signalAbortTransaction;
|
||||
boost::signals2::signal<void (const App::Document&, const std::vector<App::DocumentObject*>&)> signalSkipRecompute;
|
||||
boost::signals2::signal<void (const App::DocumentObject&)> signalFinishRestoreObject;
|
||||
boost::signals2::signal<void (const App::Document&,const App::Property&)> signalChangePropertyEditor;
|
||||
boost::signals2::signal<void(const App::Document&)> signalAbortTransaction;
|
||||
boost::signals2::signal<void(const App::Document&, const std::vector<App::DocumentObject*>&)> signalSkipRecompute;
|
||||
boost::signals2::signal<void(const App::DocumentObject&)> signalFinishRestoreObject;
|
||||
boost::signals2::signal<void(const App::Document&, const App::Property&)> signalChangePropertyEditor;
|
||||
boost::signals2::signal<void(std::string)> signalLinkXsetValue;
|
||||
// clang-format on
|
||||
//@}
|
||||
boost::signals2::signal<void (std::string)> signalLinkXsetValue;
|
||||
// NOLINTEND
|
||||
|
||||
|
||||
void clearDocument();
|
||||
@@ -192,21 +192,23 @@ public:
|
||||
/** @name File handling of the document */
|
||||
//@{
|
||||
/// Save the Document under a new Name
|
||||
//void saveAs (const char* Name);
|
||||
// void saveAs (const char* Name);
|
||||
/// Save the document to the file in Property Path
|
||||
bool save ();
|
||||
bool save();
|
||||
bool saveAs(const char* file);
|
||||
bool saveCopy(const char* file) const;
|
||||
/// Restore the document from the file in Property Path
|
||||
void restore (const char *filename=nullptr,
|
||||
bool delaySignal=false, const std::vector<std::string> &objNames={});
|
||||
bool afterRestore(bool checkPartial=false);
|
||||
bool afterRestore(const std::vector<App::DocumentObject *> &, bool checkPartial=false);
|
||||
enum ExportStatus {
|
||||
void restore(const char* filename = nullptr,
|
||||
bool delaySignal = false,
|
||||
const std::vector<std::string>& objNames = {});
|
||||
bool afterRestore(bool checkPartial = false);
|
||||
bool afterRestore(const std::vector<App::DocumentObject*>&, bool checkPartial = false);
|
||||
enum ExportStatus
|
||||
{
|
||||
NotExporting,
|
||||
Exporting,
|
||||
};
|
||||
ExportStatus isExporting(const App::DocumentObject *obj) const;
|
||||
ExportStatus isExporting(const App::DocumentObject* obj) const;
|
||||
void exportObjects(const std::vector<App::DocumentObject*>&, std::ostream&);
|
||||
void exportGraphviz(std::ostream&) const;
|
||||
std::vector<App::DocumentObject*> importObjects(Base::XMLReader& reader);
|
||||
@@ -222,10 +224,10 @@ public:
|
||||
*
|
||||
* @return the list of imported objects
|
||||
*/
|
||||
std::vector<App::DocumentObject*> importLinks(
|
||||
const std::vector<App::DocumentObject*> &objs = {});
|
||||
std::vector<App::DocumentObject*>
|
||||
importLinks(const std::vector<App::DocumentObject*>& objs = {});
|
||||
/// Opens the document from its file name
|
||||
//void open (void);
|
||||
// void open (void);
|
||||
/// Is the document already saved to a file?
|
||||
bool isSaved() const;
|
||||
/// Get the document name
|
||||
@@ -241,31 +243,39 @@ public:
|
||||
const char* getFileName() const;
|
||||
//@}
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
/// returns the complete document memory consumption, including all managed DocObjects and Undo Redo.
|
||||
unsigned int getMemSize () const override;
|
||||
/// returns the complete document memory consumption, including all managed DocObjects and Undo
|
||||
/// Redo.
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
/** @name Object handling */
|
||||
//@{
|
||||
/** Add a feature of sType with sName (ASCII) to this document and set it active.
|
||||
* Unicode names are set through the Label property.
|
||||
* @param sType the type of created object
|
||||
* @param pObjectName if nonNULL use that name otherwise generate a new unique name based on the \a sType
|
||||
* @param isNew if false don't call the \c DocumentObject::setupObject() callback (default is true)
|
||||
* @param pObjectName if nonNULL use that name otherwise generate a new unique name based on the
|
||||
* \a sType
|
||||
* @param isNew if false don't call the \c DocumentObject::setupObject() callback (default
|
||||
* is true)
|
||||
* @param viewType override object's view provider name
|
||||
* @param isPartial indicate if this object is meant to be partially loaded
|
||||
*/
|
||||
DocumentObject *addObject(const char* sType, const char* pObjectName=nullptr,
|
||||
bool isNew=true, const char *viewType=nullptr, bool isPartial=false);
|
||||
DocumentObject* addObject(const char* sType,
|
||||
const char* pObjectName = nullptr,
|
||||
bool isNew = true,
|
||||
const char* viewType = nullptr,
|
||||
bool isPartial = false);
|
||||
/** Add an array of features of the given types and names.
|
||||
* Unicode names are set through the Label property.
|
||||
* @param sType The type of created object
|
||||
* @param objectNames A list of object names
|
||||
* @param isNew If false don't call the \c DocumentObject::setupObject() callback (default is true)
|
||||
* @param isNew If false don't call the \c DocumentObject::setupObject() callback (default
|
||||
* is true)
|
||||
*/
|
||||
std::vector<DocumentObject *>addObjects(const char* sType, const std::vector<std::string>& objectNames, bool isNew=true);
|
||||
std::vector<DocumentObject*>
|
||||
addObjects(const char* sType, const std::vector<std::string>& objectNames, bool isNew = true);
|
||||
/// Remove a feature out of the document
|
||||
void removeObject(const char* sName);
|
||||
/** Add an existing feature with sName (ASCII) to this document and set it active.
|
||||
@@ -275,7 +285,7 @@ public:
|
||||
* \note The passed feature must not yet be added to a document, otherwise an exception
|
||||
* is raised.
|
||||
*/
|
||||
void addObject(DocumentObject*, const char* pObjectName=nullptr);
|
||||
void addObject(DocumentObject*, const char* pObjectName = nullptr);
|
||||
|
||||
|
||||
/** Copy objects from another document to this document
|
||||
@@ -289,40 +299,44 @@ public:
|
||||
*
|
||||
* @return Returns the list of objects copied.
|
||||
*/
|
||||
std::vector<DocumentObject*> copyObject(
|
||||
const std::vector<DocumentObject*> &objs,
|
||||
bool recursive=false, bool returnAll=false);
|
||||
std::vector<DocumentObject*> copyObject(const std::vector<DocumentObject*>& objs,
|
||||
bool recursive = false,
|
||||
bool returnAll = false);
|
||||
/** Move an object from another document to this document
|
||||
* If \a recursive is true then all objects this object depends on
|
||||
* are moved as well. By default \a recursive is false.
|
||||
* Returns the moved object itself or 0 if the object is already part of this
|
||||
* document..
|
||||
*/
|
||||
DocumentObject* moveObject(DocumentObject* obj, bool recursive=false);
|
||||
DocumentObject* moveObject(DocumentObject* obj, bool recursive = false);
|
||||
/// Returns the active Object of this document
|
||||
DocumentObject *getActiveObject() const;
|
||||
DocumentObject* getActiveObject() const;
|
||||
/// Returns a Object of this document
|
||||
DocumentObject *getObject(const char *Name) const;
|
||||
DocumentObject* getObject(const char* Name) const;
|
||||
/// Returns a Object of this document by its id
|
||||
DocumentObject *getObjectByID(long id) const;
|
||||
DocumentObject* getObjectByID(long id) const;
|
||||
/// Returns true if the DocumentObject is contained in this document
|
||||
bool isIn(const DocumentObject *pFeat) const;
|
||||
bool isIn(const DocumentObject* pFeat) const;
|
||||
/// Returns a Name of an Object or 0
|
||||
const char *getObjectName(DocumentObject *pFeat) const;
|
||||
const char* getObjectName(DocumentObject* pFeat) const;
|
||||
/// Returns a Name of an Object or 0
|
||||
std::string getUniqueObjectName(const char *Name) const;
|
||||
std::string getUniqueObjectName(const char* Name) const;
|
||||
/// Returns a name of the form prefix_number. d specifies the number of digits.
|
||||
std::string getStandardObjectName(const char *Name, int d) const;
|
||||
std::string getStandardObjectName(const char* Name, int d) const;
|
||||
/// Returns a list of document's objects including the dependencies
|
||||
std::vector<DocumentObject*> getDependingObjects() const;
|
||||
/// Returns a list of all Objects
|
||||
const std::vector<DocumentObject*> &getObjects() const;
|
||||
const std::vector<DocumentObject*>& getObjects() const;
|
||||
std::vector<DocumentObject*> getObjectsOfType(const Base::Type& typeId) const;
|
||||
/// Returns all object with given extensions. If derived=true also all objects with extensions derived from the given one
|
||||
std::vector<DocumentObject*> getObjectsWithExtension(const Base::Type& typeId, bool derived = true) const;
|
||||
std::vector<DocumentObject*> findObjects(const Base::Type& typeId, const char* objname, const char* label) const;
|
||||
/// Returns all object with given extensions. If derived=true also all objects with extensions
|
||||
/// derived from the given one
|
||||
std::vector<DocumentObject*> getObjectsWithExtension(const Base::Type& typeId,
|
||||
bool derived = true) const;
|
||||
std::vector<DocumentObject*>
|
||||
findObjects(const Base::Type& typeId, const char* objname, const char* label) const;
|
||||
/// Returns an array with the correct types already.
|
||||
template<typename T> inline std::vector<T*> getObjectsOfType() const;
|
||||
template<typename T>
|
||||
inline std::vector<T*> getObjectsOfType() const;
|
||||
int countObjectsOfType(const Base::Type& typeId) const;
|
||||
/// get the number of objects in the document
|
||||
int countObjects() const;
|
||||
@@ -338,7 +352,7 @@ public:
|
||||
/// check if there is any object must execute in this document
|
||||
bool mustExecute() const;
|
||||
/// returns all touched objects
|
||||
std::vector<App::DocumentObject *> getTouched() const;
|
||||
std::vector<App::DocumentObject*> getTouched() const;
|
||||
/// set the document to be closable, this is on by default.
|
||||
void setClosable(bool);
|
||||
/// check whether the document can be closed
|
||||
@@ -348,10 +362,12 @@ public:
|
||||
* @param objs: specify a sub set of objects to recompute. If empty, then
|
||||
* all object in this document is checked for recompute
|
||||
*/
|
||||
int recompute(const std::vector<App::DocumentObject*> &objs={},
|
||||
bool force=false,bool *hasError=nullptr, int options=0);
|
||||
int recompute(const std::vector<App::DocumentObject*>& objs = {},
|
||||
bool force = false,
|
||||
bool* hasError = nullptr,
|
||||
int options = 0);
|
||||
/// Recompute only one feature
|
||||
bool recomputeFeature(DocumentObject* Feat,bool recursive=false);
|
||||
bool recomputeFeature(DocumentObject* Feat, bool recursive = false);
|
||||
/// get the text of the error of a specified object
|
||||
const char* getErrorDescription(const App::DocumentObject*) const;
|
||||
/// return the status bits
|
||||
@@ -392,9 +408,9 @@ public:
|
||||
* to setup a potential transaction which will only be created if there is
|
||||
* actual changes.
|
||||
*/
|
||||
void openTransaction(const char* name=nullptr);
|
||||
void openTransaction(const char* name = nullptr);
|
||||
/// Rename the current transaction if the id matches
|
||||
void renameTransaction(const char *name, int id);
|
||||
void renameTransaction(const char* name, int id);
|
||||
/// Commit the Command transaction. Do nothing If there is no Command transaction open.
|
||||
void commitTransaction();
|
||||
/// Abort the actually running transaction.
|
||||
@@ -402,49 +418,51 @@ public:
|
||||
/// Check if a transaction is open
|
||||
bool hasPendingTransaction() const;
|
||||
/// Return the undo/redo transaction ID starting from the back
|
||||
int getTransactionID(bool undo, unsigned pos=0) const;
|
||||
int getTransactionID(bool undo, unsigned pos = 0) const;
|
||||
/// Check if a transaction is open and its list is empty.
|
||||
/// If no transaction is open true is returned.
|
||||
bool isTransactionEmpty() const;
|
||||
/// Set the Undo limit in Byte!
|
||||
void setUndoLimit(unsigned int UndoMemSize=0);
|
||||
void setUndoLimit(unsigned int UndoMemSize = 0);
|
||||
/// Returns the actual memory consumption of the Undo redo stuff.
|
||||
unsigned int getUndoMemSize () const;
|
||||
unsigned int getUndoMemSize() const;
|
||||
/// Set the Undo limit as stack size
|
||||
void setMaxUndoStackSize(unsigned int UndoMaxStackSize=20);
|
||||
void setMaxUndoStackSize(unsigned int UndoMaxStackSize = 20); // NOLINT
|
||||
/// Set the Undo limit as stack size
|
||||
unsigned int getMaxUndoStackSize()const;
|
||||
unsigned int getMaxUndoStackSize() const;
|
||||
/// Remove all stored Undos and Redos
|
||||
void clearUndos();
|
||||
/// Returns the number of stored Undos. If greater than 0 Undo will be effective.
|
||||
int getAvailableUndos(int id=0) const;
|
||||
int getAvailableUndos(int id = 0) const;
|
||||
/// Returns a list of the Undo names
|
||||
std::vector<std::string> getAvailableUndoNames() const;
|
||||
/// Will UNDO one step, returns False if no undo was done (Undos == 0).
|
||||
bool undo(int id=0);
|
||||
bool undo(int id = 0);
|
||||
/// Returns the number of stored Redos. If greater than 0 Redo will be effective.
|
||||
int getAvailableRedos(int id=0) const;
|
||||
int getAvailableRedos(int id = 0) const;
|
||||
/// Returns a list of the Redo names.
|
||||
std::vector<std::string> getAvailableRedoNames() const;
|
||||
/// Will REDO one step, returns False if no redo was done (Redos == 0).
|
||||
bool redo(int id=0) ;
|
||||
/// returns true if the document is in an Transaction phase, e.g. currently performing a redo/undo or rollback
|
||||
bool redo(int id = 0);
|
||||
/// returns true if the document is in an Transaction phase, e.g. currently performing a
|
||||
/// redo/undo or rollback
|
||||
bool isPerformingTransaction() const;
|
||||
/// \internal add or remove property from a transactional object
|
||||
void addOrRemovePropertyOfObject(TransactionalObject*, Property *prop, bool add);
|
||||
void addOrRemovePropertyOfObject(TransactionalObject*, Property* prop, bool add);
|
||||
//@}
|
||||
|
||||
/** @name dependency stuff */
|
||||
//@{
|
||||
/// write GraphViz file
|
||||
void writeDependencyGraphViz(std::ostream &out);
|
||||
void writeDependencyGraphViz(std::ostream& out);
|
||||
/// checks if the graph is directed and has no cycles
|
||||
bool checkOnCycle();
|
||||
/// get a list of all objects linking to the given object
|
||||
std::vector<App::DocumentObject*> getInList(const DocumentObject* me) const;
|
||||
|
||||
/// Option bit flags used by getDepenencyList()
|
||||
enum DependencyOption {
|
||||
enum DependencyOption
|
||||
{
|
||||
/// Return topological sorted list
|
||||
DepSort = 1,
|
||||
/// Do no include object linked by PropertyXLink, as it can handle external link
|
||||
@@ -461,14 +479,15 @@ public:
|
||||
* @param objs: input objects to query for dependency.
|
||||
* @param options: See DependencyOption
|
||||
*/
|
||||
static std::vector<App::DocumentObject*> getDependencyList(
|
||||
const std::vector<App::DocumentObject*> &objs, int options=0);
|
||||
static std::vector<App::DocumentObject*>
|
||||
getDependencyList(const std::vector<App::DocumentObject*>& objs, int options = 0);
|
||||
|
||||
std::vector<App::Document*> getDependentDocuments(bool sort=true);
|
||||
static std::vector<App::Document*> getDependentDocuments(std::vector<App::Document*> docs, bool sort);
|
||||
std::vector<App::Document*> getDependentDocuments(bool sort = true);
|
||||
static std::vector<App::Document*> getDependentDocuments(std::vector<App::Document*> docs,
|
||||
bool sort);
|
||||
|
||||
// set Changed
|
||||
//void setChanged(DocumentObject* change);
|
||||
// void setChanged(DocumentObject* change);
|
||||
/// get a list of topological sorted objects (https://en.wikipedia.org/wiki/Topological_sorting)
|
||||
std::vector<App::DocumentObject*> topologicalSort() const;
|
||||
/// get all root objects (objects no other one reference too)
|
||||
@@ -476,8 +495,8 @@ public:
|
||||
/// get all tree root objects (objects that are at the root of the object tree)
|
||||
std::vector<App::DocumentObject*> getRootObjectsIgnoreLinks() const;
|
||||
/// get all possible paths from one object to another following the OutList
|
||||
std::vector<std::list<App::DocumentObject*> > getPathsByOutList
|
||||
(const App::DocumentObject* from, const App::DocumentObject* to) const;
|
||||
std::vector<std::list<App::DocumentObject*>>
|
||||
getPathsByOutList(const App::DocumentObject* from, const App::DocumentObject* to) const;
|
||||
//@}
|
||||
|
||||
/** Called by a property during save to store its StringHasher
|
||||
@@ -493,7 +512,7 @@ public:
|
||||
* of the hasher. If the hasher has not been added before, the object must
|
||||
* save the hasher by calling StringHasher::Save
|
||||
*/
|
||||
std::pair<bool,int> addStringHasher(const StringHasherRef & hasher) const;
|
||||
std::pair<bool, int> addStringHasher(const StringHasherRef& hasher) const;
|
||||
|
||||
/** Called by property to restore its StringHasher
|
||||
*
|
||||
@@ -505,7 +524,7 @@ public:
|
||||
* The caller is responsible for restoring the hasher if the caller is the first
|
||||
* owner of the hasher, i.e. if addStringHasher() returns true during save.
|
||||
*/
|
||||
StringHasherRef getStringHasher(int index=-1) const;
|
||||
StringHasherRef getStringHasher(int index = -1) const;
|
||||
|
||||
/** Return the links to a given object
|
||||
*
|
||||
@@ -516,22 +535,32 @@ public:
|
||||
* @param objs: optional objects to search for, if empty, then all objects
|
||||
* of this document are searched.
|
||||
*/
|
||||
void getLinksTo(std::set<DocumentObject*> &links,
|
||||
const DocumentObject *obj, int options, int maxCount=0,
|
||||
const std::vector<DocumentObject*> &objs = {}) const;
|
||||
void getLinksTo(std::set<DocumentObject*>& links,
|
||||
const DocumentObject* obj,
|
||||
int options,
|
||||
int maxCount = 0,
|
||||
const std::vector<DocumentObject*>& objs = {}) const;
|
||||
|
||||
/// Check if there is any link to the given object
|
||||
bool hasLinksTo(const DocumentObject *obj) const;
|
||||
bool hasLinksTo(const DocumentObject* obj) const;
|
||||
|
||||
/// Called by objects during restore to ask for recompute
|
||||
void addRecomputeObject(DocumentObject *obj);
|
||||
void addRecomputeObject(DocumentObject* obj);
|
||||
|
||||
const std::string &getOldLabel() const {return oldLabel;}
|
||||
const std::string& getOldLabel() const
|
||||
{
|
||||
return oldLabel;
|
||||
}
|
||||
|
||||
/// Function called to signal that an object identifier has been renamed
|
||||
void renameObjectIdentifiers(const std::map<App::ObjectIdentifier, App::ObjectIdentifier> & paths, const std::function<bool(const App::DocumentObject*)> &selector = [](const App::DocumentObject *) { return true; });
|
||||
void renameObjectIdentifiers(
|
||||
const std::map<App::ObjectIdentifier, App::ObjectIdentifier>& paths,
|
||||
const std::function<bool(const App::DocumentObject*)>& selector =
|
||||
[](const App::DocumentObject*) {
|
||||
return true;
|
||||
});
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
std::string getFullName() const override;
|
||||
|
||||
@@ -550,23 +579,23 @@ public:
|
||||
|
||||
protected:
|
||||
/// Construction
|
||||
explicit Document(const char *documentName = "");
|
||||
explicit Document(const char* documentName = "");
|
||||
|
||||
void _removeObject(DocumentObject* pcObject);
|
||||
void _addObject(DocumentObject* pcObject, const char* pObjectName);
|
||||
/// checks if a valid transaction is open
|
||||
void _checkTransaction(DocumentObject* pcDelObj, const Property *What, int line);
|
||||
void _checkTransaction(DocumentObject* pcDelObj, const Property* What, int line);
|
||||
void breakDependency(DocumentObject* pcObject, bool clear);
|
||||
std::vector<App::DocumentObject*> readObjects(Base::XMLReader& reader);
|
||||
void writeObjects(const std::vector<App::DocumentObject*>&, Base::Writer &writer) const;
|
||||
void writeObjects(const std::vector<App::DocumentObject*>&, Base::Writer& writer) const;
|
||||
bool saveToFile(const char* filename) const;
|
||||
|
||||
void onBeforeChange(const Property* prop) override;
|
||||
void onChanged(const Property* prop) override;
|
||||
/// callback from the Document objects before property will be changed
|
||||
void onBeforeChangeProperty(const TransactionalObject *Who, const Property *What);
|
||||
void onBeforeChangeProperty(const TransactionalObject* Who, const Property* What);
|
||||
/// callback from the Document objects after property was changed
|
||||
void onChangedProperty(const DocumentObject *Who, const Property *What);
|
||||
void onChangedProperty(const DocumentObject* Who, const Property* What);
|
||||
/// helper which Recompute only this feature
|
||||
/// @return 0 if succeeded, 1 if failed, -1 if aborted by user.
|
||||
int _recomputeFeature(DocumentObject* Feat);
|
||||
@@ -574,9 +603,10 @@ protected:
|
||||
|
||||
/// refresh the internal dependency graph
|
||||
void _rebuildDependencyList(
|
||||
const std::vector<App::DocumentObject*> &objs = std::vector<App::DocumentObject*>());
|
||||
const std::vector<App::DocumentObject*>& objs = std::vector<App::DocumentObject*>());
|
||||
|
||||
std::string getTransientDirectoryName(const std::string& uuid, const std::string& filename) const;
|
||||
std::string getTransientDirectoryName(const std::string& uuid,
|
||||
const std::string& filename) const;
|
||||
|
||||
/** Open a new command Undo/Redo, an UTF-8 name can be specified
|
||||
*
|
||||
@@ -588,18 +618,19 @@ protected:
|
||||
* This function creates an actual transaction regardless of Application
|
||||
* AutoTransaction setting.
|
||||
*/
|
||||
int _openTransaction(const char* name=nullptr, int id=0);
|
||||
int _openTransaction(const char* name = nullptr, int id = 0);
|
||||
/// Internally called by App::Application to commit the Command transaction.
|
||||
void _commitTransaction(bool notify=false);
|
||||
void _commitTransaction(bool notify = false);
|
||||
/// Internally called by App::Application to abort the running transaction.
|
||||
void _abortTransaction();
|
||||
|
||||
private:
|
||||
// # Data Member of the document +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// # Data Member of the document
|
||||
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
std::list<Transaction*> mUndoTransactions;
|
||||
std::map<int,Transaction*> mUndoMap;
|
||||
std::map<int, Transaction*> mUndoMap;
|
||||
std::list<Transaction*> mRedoTransactions;
|
||||
std::map<int,Transaction*> mRedoMap;
|
||||
std::map<int, Transaction*> mRedoMap;
|
||||
|
||||
struct DocumentP* d;
|
||||
|
||||
@@ -613,12 +644,13 @@ inline std::vector<T*> Document::getObjectsOfType() const
|
||||
std::vector<T*> type;
|
||||
std::vector<App::DocumentObject*> obj = this->getObjectsOfType(T::getClassTypeId());
|
||||
type.reserve(obj.size());
|
||||
for (std::vector<App::DocumentObject*>::iterator it = obj.begin(); it != obj.end(); ++it)
|
||||
type.push_back(static_cast<T*>(*it));
|
||||
for (auto it : obj) {
|
||||
type.push_back(static_cast<T*>(it));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
} //namespace App
|
||||
} // namespace App
|
||||
|
||||
#endif // APP_DOCUMENT_H
|
||||
#endif // APP_DOCUMENT_H
|
||||
|
||||
+468
-346
File diff suppressed because it is too large
Load Diff
+216
-124
@@ -46,44 +46,49 @@ class DocumentObjectGroup;
|
||||
class DocumentObjectPy;
|
||||
class Expression;
|
||||
|
||||
enum ObjectStatus {
|
||||
// clang-format off
|
||||
enum ObjectStatus
|
||||
{
|
||||
Touch = 0,
|
||||
Error = 1,
|
||||
New = 2,
|
||||
Recompute = 3, // set when the object is currently being recomputed
|
||||
Recompute = 3, // set when the object is currently being recomputed
|
||||
Restore = 4,
|
||||
Remove = 5,
|
||||
PythonCall = 6,
|
||||
Destroy = 7,
|
||||
Enforce = 8,
|
||||
Recompute2 = 9, // set when the object is being recomputed in the second pass
|
||||
Recompute2 = 9, // set when the object is being recomputed in the second pass
|
||||
PartialObject = 10,
|
||||
PendingRecompute = 11, // set by Document, indicating the object is in recomputation queue
|
||||
ObjImporting = 13, // Mark the object as importing
|
||||
NoTouch = 14, // no touch on any property change
|
||||
GeoExcluded = 15, // mark as a member but not claimed by GeoFeatureGroup
|
||||
Expand = 16, // indicate the object's tree item expansion status
|
||||
NoAutoExpand = 17, // disable tree item auto expand on selection for this object
|
||||
PendingTransactionUpdate = 18, // mark that the object expects a call to onUndoRedoFinished() after transaction is finished.
|
||||
RecomputeExtension = 19, // mark the object to recompute its extensions
|
||||
TouchOnColorChange = 20, // inform view provider touch object on color change
|
||||
Freeze = 21, // do not recompute ever
|
||||
PendingRecompute = 11, // set by Document, indicating the object is in recomputation queue
|
||||
ObjImporting = 13, // Mark the object as importing
|
||||
NoTouch = 14, // no touch on any property change
|
||||
GeoExcluded = 15, // mark as a member but not claimed by GeoFeatureGroup
|
||||
Expand = 16, // indicate the object's tree item expansion status
|
||||
NoAutoExpand = 17, // disable tree item auto expand on selection for this object
|
||||
PendingTransactionUpdate = 18, // mark that the object expects a call to onUndoRedoFinished() after transaction is finished.
|
||||
RecomputeExtension = 19, // mark the object to recompute its extensions
|
||||
TouchOnColorChange = 20, // inform view provider touch object on color change
|
||||
Freeze = 21, // do not recompute ever
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
/** Return object for feature execution
|
||||
*/
|
||||
*/
|
||||
class AppExport DocumentObjectExecReturn
|
||||
{
|
||||
public:
|
||||
explicit DocumentObjectExecReturn(const std::string& sWhy, DocumentObject* WhichObject=nullptr)
|
||||
: Why(sWhy), Which(WhichObject)
|
||||
{
|
||||
}
|
||||
explicit DocumentObjectExecReturn(const char* sWhy, DocumentObject* WhichObject=nullptr)
|
||||
explicit DocumentObjectExecReturn(const std::string& sWhy,
|
||||
DocumentObject* WhichObject = nullptr)
|
||||
: Why(sWhy)
|
||||
, Which(WhichObject)
|
||||
{}
|
||||
explicit DocumentObjectExecReturn(const char* sWhy, DocumentObject* WhichObject = nullptr)
|
||||
: Which(WhichObject)
|
||||
{
|
||||
if (sWhy)
|
||||
if (sWhy) {
|
||||
Why = sWhy;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Why;
|
||||
@@ -91,7 +96,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Base class of all Classes handled in the Document
|
||||
*/
|
||||
class AppExport DocumentObject: public App::TransactionalObject
|
||||
@@ -99,7 +103,6 @@ class AppExport DocumentObject: public App::TransactionalObject
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(App::DocumentObject);
|
||||
|
||||
public:
|
||||
|
||||
PropertyString Label;
|
||||
PropertyString Label2;
|
||||
PropertyExpressionEngine ExpressionEngine;
|
||||
@@ -107,15 +110,18 @@ public:
|
||||
/// Allow control visibility status in App name space
|
||||
PropertyBool Visibility;
|
||||
|
||||
// clang-format off
|
||||
/// signal before changing a property of this object
|
||||
boost::signals2::signal<void (const App::DocumentObject&, const App::Property&)> signalBeforeChange;
|
||||
boost::signals2::signal<void(const App::DocumentObject&, const App::Property&)> signalBeforeChange;
|
||||
/// signal on changed property of this object
|
||||
boost::signals2::signal<void (const App::DocumentObject&, const App::Property&)> signalChanged;
|
||||
boost::signals2::signal<void(const App::DocumentObject&, const App::Property&)> signalChanged;
|
||||
/// signal on changed property of this object before document scoped signalChangedObject
|
||||
boost::signals2::signal<void (const App::DocumentObject&, const App::Property&)> signalEarlyChanged;
|
||||
boost::signals2::signal<void(const App::DocumentObject&, const App::Property&)> signalEarlyChanged;
|
||||
// clang-format on
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
virtual const char* getViewProviderName() const {
|
||||
virtual const char* getViewProviderName() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
/**
|
||||
@@ -127,7 +133,8 @@ public:
|
||||
* If not, the view provider will be reverted to the one returned from \ref
|
||||
* getViewProviderName().
|
||||
*/
|
||||
virtual const char *getViewProviderNameOverride() const {
|
||||
virtual const char* getViewProviderNameOverride() const
|
||||
{
|
||||
return getViewProviderName();
|
||||
}
|
||||
|
||||
@@ -138,11 +145,14 @@ public:
|
||||
/// returns a value that uniquely identifies this DocumentObject.
|
||||
const char* getDagKey() const;
|
||||
/// returns the name which is set in the document for this object (not the name property!)
|
||||
const char *getNameInDocument() const;
|
||||
const char* getNameInDocument() const;
|
||||
/// Return the object ID that is unique within its owner document
|
||||
long getID() const {return _Id;}
|
||||
long getID() const
|
||||
{
|
||||
return _Id;
|
||||
}
|
||||
/// returns the name that is safe to be exported to other document
|
||||
std::string getExportName(bool forced=false) const;
|
||||
std::string getExportName(bool forced = false) const;
|
||||
/// Return the object full name of the form DocName#ObjName
|
||||
std::string getFullName() const override;
|
||||
/// Return the object full label in the form DocName#ObjName
|
||||
@@ -150,13 +160,13 @@ public:
|
||||
bool isAttachedToDocument() const override;
|
||||
const char* detachFromDocument() override;
|
||||
/// gets the document in which this Object is handled
|
||||
App::Document *getDocument() const;
|
||||
App::Document* getDocument() const;
|
||||
|
||||
/** Set the property touched -> changed, cause recomputation in Update()
|
||||
*/
|
||||
//@{
|
||||
/// set this document object touched (cause recomputation on dependent features)
|
||||
void touch(bool noRecompute=false);
|
||||
void touch(bool noRecompute = false);
|
||||
/// test if this document object is touched
|
||||
bool isTouched() const;
|
||||
/// Enforce this document object to be recomputed
|
||||
@@ -164,32 +174,63 @@ public:
|
||||
/// Test if this document object must be recomputed
|
||||
bool mustRecompute() const;
|
||||
/// reset this document object touched
|
||||
void purgeTouched() {
|
||||
void purgeTouched()
|
||||
{
|
||||
StatusBits.reset(ObjectStatus::Touch);
|
||||
StatusBits.reset(ObjectStatus::Enforce);
|
||||
setPropertyStatus(0,false);
|
||||
setPropertyStatus(0, false);
|
||||
}
|
||||
/// set this feature to error
|
||||
bool isError() const {return StatusBits.test(ObjectStatus::Error);}
|
||||
bool isValid() const {return !StatusBits.test(ObjectStatus::Error);}
|
||||
bool isError() const
|
||||
{
|
||||
return StatusBits.test(ObjectStatus::Error);
|
||||
}
|
||||
bool isValid() const
|
||||
{
|
||||
return !StatusBits.test(ObjectStatus::Error);
|
||||
}
|
||||
/// remove the error from the object
|
||||
void purgeError(){StatusBits.reset(ObjectStatus::Error);}
|
||||
void purgeError()
|
||||
{
|
||||
StatusBits.reset(ObjectStatus::Error);
|
||||
}
|
||||
/// returns true if this objects is currently recomputing
|
||||
bool isRecomputing() const {return StatusBits.test(ObjectStatus::Recompute);}
|
||||
bool isRecomputing() const
|
||||
{
|
||||
return StatusBits.test(ObjectStatus::Recompute);
|
||||
}
|
||||
/// returns true if this objects is currently restoring from file
|
||||
bool isRestoring() const {return StatusBits.test(ObjectStatus::Restore);}
|
||||
bool isRestoring() const
|
||||
{
|
||||
return StatusBits.test(ObjectStatus::Restore);
|
||||
}
|
||||
/// returns true if this objects is currently removed from the document
|
||||
bool isRemoving() const {return StatusBits.test(ObjectStatus::Remove);}
|
||||
bool isRemoving() const
|
||||
{
|
||||
return StatusBits.test(ObjectStatus::Remove);
|
||||
}
|
||||
/// set this document object freezed (prevent recomputation)
|
||||
void freeze();
|
||||
/// set this document object unfreezed (and touch it)
|
||||
void unfreeze(bool noRecompute=false);
|
||||
void unfreeze(bool noRecompute = false);
|
||||
/// returns true if this objects is currently freezed
|
||||
bool isFreezed() const {return StatusBits.test(ObjectStatus::Freeze);}
|
||||
bool isFreezed() const
|
||||
{
|
||||
return StatusBits.test(ObjectStatus::Freeze);
|
||||
}
|
||||
/// return the status bits
|
||||
unsigned long getStatus() const {return StatusBits.to_ulong();}
|
||||
bool testStatus(ObjectStatus pos) const {return StatusBits.test(size_t(pos));}
|
||||
void setStatus(ObjectStatus pos, bool on) {StatusBits.set(size_t(pos), on);}
|
||||
unsigned long getStatus() const
|
||||
{
|
||||
return StatusBits.to_ulong();
|
||||
}
|
||||
bool testStatus(ObjectStatus pos) const
|
||||
{
|
||||
return StatusBits.test(size_t(pos));
|
||||
}
|
||||
void setStatus(ObjectStatus pos, bool on)
|
||||
{
|
||||
StatusBits.set(size_t(pos), on);
|
||||
}
|
||||
//@}
|
||||
|
||||
int isExporting() const;
|
||||
@@ -205,14 +246,14 @@ public:
|
||||
* @return -1 if element visibility is not supported, 0 if element is not
|
||||
* found, 1 if success
|
||||
*/
|
||||
virtual int setElementVisible(const char *element, bool visible);
|
||||
virtual int setElementVisible(const char* element, bool visible);
|
||||
|
||||
/** Get sub-element visibility
|
||||
*
|
||||
* @return -1 if element visibility is not supported or element not found, 0
|
||||
* if element is invisible, or else 1
|
||||
*/
|
||||
virtual int isElementVisible(const char *element) const;
|
||||
virtual int isElementVisible(const char* element) const;
|
||||
|
||||
/// return true to activate tree view group object handling and element visibility
|
||||
virtual bool hasChildElement() const;
|
||||
@@ -225,7 +266,8 @@ public:
|
||||
*/
|
||||
//@{
|
||||
/// OutList options
|
||||
enum OutListOption {
|
||||
enum OutListOption
|
||||
{
|
||||
/// Do not include link from expression engine
|
||||
OutListNoExpression = 1,
|
||||
/// Do not hide any link (i.e. include links with LinkScopeHidden)
|
||||
@@ -234,9 +276,9 @@ public:
|
||||
OutListNoXLinked = 4,
|
||||
};
|
||||
/// returns a list of objects this object is pointing to by Links
|
||||
const std::vector<App::DocumentObject*> &getOutList() const;
|
||||
const std::vector<App::DocumentObject*>& getOutList() const;
|
||||
std::vector<App::DocumentObject*> getOutList(int option) const;
|
||||
void getOutList(int option, std::vector<App::DocumentObject*> &res) const;
|
||||
void getOutList(int option, std::vector<App::DocumentObject*>& res) const;
|
||||
|
||||
/// returns a list of objects linked by the property
|
||||
std::vector<App::DocumentObject*> getOutListOfProperty(App::Property*) const;
|
||||
@@ -245,15 +287,15 @@ public:
|
||||
/// clear internal out list cache
|
||||
void clearOutListCache() const;
|
||||
/// get all possible paths from this to another object following the OutList
|
||||
std::vector<std::list<App::DocumentObject*> > getPathsByOutList(App::DocumentObject* to) const;
|
||||
std::vector<std::list<App::DocumentObject*>> getPathsByOutList(App::DocumentObject* to) const;
|
||||
#ifdef USE_OLD_DAG
|
||||
/// get all objects link to this object
|
||||
std::vector<App::DocumentObject*> getInList(void) const
|
||||
#else
|
||||
const std::vector<App::DocumentObject*> &getInList() const;
|
||||
const std::vector<App::DocumentObject*>& getInList() const;
|
||||
#endif
|
||||
/// get all objects link directly or indirectly to this object
|
||||
std::vector<App::DocumentObject*> getInListRecursive() const;
|
||||
/// get all objects link directly or indirectly to this object
|
||||
std::vector<App::DocumentObject*> getInListRecursive() const;
|
||||
/** Get a set of all objects linking to this object, including possible external parent objects
|
||||
*
|
||||
* @param inSet [out]: a set containing all objects linking to this object.
|
||||
@@ -261,9 +303,11 @@ public:
|
||||
* @param inList [in, out]: optional pointer to a vector holding the output
|
||||
* objects, with the furthest linking object ordered last.
|
||||
*/
|
||||
void getInListEx(std::set<App::DocumentObject*> &inSet,
|
||||
bool recursive, std::vector<App::DocumentObject*> *inList=nullptr) const;
|
||||
/** Return a set of all objects linking to this object, including possible external parent objects
|
||||
void getInListEx(std::set<App::DocumentObject*>& inSet,
|
||||
bool recursive,
|
||||
std::vector<App::DocumentObject*>* inList = nullptr) const;
|
||||
/** Return a set of all objects linking to this object, including possible external parent
|
||||
* objects
|
||||
* @param recursive [in]: whether to obtain recursive in list
|
||||
*/
|
||||
std::set<App::DocumentObject*> getInListEx(bool recursive) const;
|
||||
@@ -296,9 +340,9 @@ public:
|
||||
* That is, if the return is true, the link is allowed.
|
||||
*/
|
||||
bool testIfLinkDAGCompatible(DocumentObject* linkTo) const;
|
||||
bool testIfLinkDAGCompatible(const std::vector<DocumentObject *> &linksTo) const;
|
||||
bool testIfLinkDAGCompatible(App::PropertyLinkSubList &linksTo) const;
|
||||
bool testIfLinkDAGCompatible(App::PropertyLinkSub &linkTo) const;
|
||||
bool testIfLinkDAGCompatible(const std::vector<DocumentObject*>& linksTo) const;
|
||||
bool testIfLinkDAGCompatible(App::PropertyLinkSubList& linksTo) const;
|
||||
bool testIfLinkDAGCompatible(App::PropertyLinkSub& linkTo) const;
|
||||
|
||||
/** Return the element map version of the geometry data stored in the given property
|
||||
*
|
||||
@@ -309,10 +353,11 @@ public:
|
||||
*
|
||||
* @return Return the element map version string.
|
||||
*/
|
||||
virtual std::string getElementMapVersion(const App::Property *prop, bool restored=false) const;
|
||||
virtual std::string getElementMapVersion(const App::Property* prop,
|
||||
bool restored = false) const;
|
||||
|
||||
/// Return true to signal re-generation of geometry element names
|
||||
virtual bool checkElementMapVersion(const App::Property *prop, const char *ver) const;
|
||||
virtual bool checkElementMapVersion(const App::Property* prop, const char* ver) const;
|
||||
|
||||
public:
|
||||
/** mustExecute
|
||||
@@ -332,10 +377,10 @@ public:
|
||||
*
|
||||
* @param recursive: set to true to recompute any dependent objects as well
|
||||
*/
|
||||
bool recomputeFeature(bool recursive=false);
|
||||
bool recomputeFeature(bool recursive = false);
|
||||
|
||||
/// get the status Message
|
||||
const char *getStatusString() const;
|
||||
const char* getStatusString() const;
|
||||
|
||||
/** Called in case of losing a link
|
||||
* Get called by the document when a object got deleted a link property of this
|
||||
@@ -344,7 +389,7 @@ public:
|
||||
* additional or different behavior.
|
||||
*/
|
||||
virtual void onLostLinkToObject(DocumentObject*);
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
/** Get the sub element/object by name
|
||||
*
|
||||
@@ -374,8 +419,11 @@ public:
|
||||
* then it shall return itself. If subname is invalid, then it shall return
|
||||
* zero.
|
||||
*/
|
||||
virtual DocumentObject *getSubObject(const char *subname, PyObject **pyObj=nullptr,
|
||||
Base::Matrix4D *mat=nullptr, bool transform=true, int depth=0) const;
|
||||
virtual DocumentObject* getSubObject(const char* subname,
|
||||
PyObject** pyObj = nullptr,
|
||||
Base::Matrix4D* mat = nullptr,
|
||||
bool transform = true,
|
||||
int depth = 0) const;
|
||||
|
||||
/** Return a list of objects referenced by a given subname including this object
|
||||
* @param subname: the sub name path
|
||||
@@ -391,7 +439,8 @@ public:
|
||||
bool flatten = false) const;
|
||||
|
||||
/// reason of calling getSubObjects()
|
||||
enum GSReason {
|
||||
enum GSReason
|
||||
{
|
||||
/// default, mostly for exporting shape objects
|
||||
GS_DEFAULT,
|
||||
/// for element selection
|
||||
@@ -413,10 +462,10 @@ public:
|
||||
* need special transformation. For example, sub objects of an array type
|
||||
* of object.
|
||||
*/
|
||||
virtual std::vector<std::string> getSubObjects(int reason=0) const;
|
||||
virtual std::vector<std::string> getSubObjects(int reason = 0) const;
|
||||
|
||||
///Obtain top parents and subnames of this object using its InList
|
||||
std::vector<std::pair<App::DocumentObject*,std::string> > getParents(int depth=0) const;
|
||||
/// Obtain top parents and subnames of this object using its InList
|
||||
std::vector<std::pair<App::DocumentObject*, std::string>> getParents(int depth = 0) const;
|
||||
|
||||
/// Obtain the first parent group of this object
|
||||
App::DocumentObject* getFirstParent() const;
|
||||
@@ -436,20 +485,34 @@ public:
|
||||
* @return Return the linked object. This function must return itself if the
|
||||
* it is not a link or the link is invalid.
|
||||
*/
|
||||
virtual DocumentObject *getLinkedObject(bool recurse=true,
|
||||
Base::Matrix4D *mat=nullptr, bool transform=false, int depth=0) const;
|
||||
virtual DocumentObject* getLinkedObject(bool recurse = true,
|
||||
Base::Matrix4D* mat = nullptr,
|
||||
bool transform = false,
|
||||
int depth = 0) const;
|
||||
|
||||
/* Return true to cause PropertyView to show linked object's property */
|
||||
virtual bool canLinkProperties() const {return true;}
|
||||
virtual bool canLinkProperties() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return whether this object is a link */
|
||||
virtual bool isLink() const {return false;};
|
||||
virtual bool isLink() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return whether this object is a link group */
|
||||
virtual bool isLinkGroup() const {return false;};
|
||||
virtual bool isLinkGroup() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return true to bypass duplicate label checking */
|
||||
virtual bool allowDuplicateLabel() const {return false;}
|
||||
virtual bool allowDuplicateLabel() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*** Called to let object itself control relabeling
|
||||
*
|
||||
@@ -457,38 +520,50 @@ public:
|
||||
*
|
||||
* This function is called before onBeforeChange()
|
||||
*/
|
||||
virtual void onBeforeChangeLabel(std::string &newLabel) {(void)newLabel;}
|
||||
virtual void onBeforeChangeLabel(std::string& newLabel)
|
||||
{
|
||||
(void)newLabel;
|
||||
}
|
||||
|
||||
friend class Document;
|
||||
friend class Transaction;
|
||||
friend class ObjectExecution;
|
||||
|
||||
static DocumentObjectExecReturn *StdReturn;
|
||||
static DocumentObjectExecReturn* StdReturn;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
|
||||
/* Expression support */
|
||||
|
||||
virtual void setExpression(const ObjectIdentifier & path, std::shared_ptr<App::Expression> expr);
|
||||
virtual void setExpression(const ObjectIdentifier& path, std::shared_ptr<App::Expression> expr);
|
||||
|
||||
void clearExpression(const ObjectIdentifier & path);
|
||||
void clearExpression(const ObjectIdentifier& path);
|
||||
|
||||
virtual const PropertyExpressionEngine::ExpressionInfo getExpression(const ObjectIdentifier &path) const;
|
||||
virtual const PropertyExpressionEngine::ExpressionInfo
|
||||
getExpression(const ObjectIdentifier& path) const;
|
||||
|
||||
virtual void renameObjectIdentifiers(const std::map<App::ObjectIdentifier, App::ObjectIdentifier> & paths);
|
||||
virtual void
|
||||
renameObjectIdentifiers(const std::map<App::ObjectIdentifier, App::ObjectIdentifier>& paths);
|
||||
|
||||
const std::string & getOldLabel() const { return oldLabel; }
|
||||
const std::string& getOldLabel() const
|
||||
{
|
||||
return oldLabel;
|
||||
}
|
||||
|
||||
const char *getViewProviderNameStored() const {
|
||||
const char* getViewProviderNameStored() const
|
||||
{
|
||||
return _pcViewProviderName.c_str();
|
||||
}
|
||||
|
||||
bool removeDynamicProperty(const char* prop) override;
|
||||
|
||||
App::Property* addDynamicProperty(
|
||||
const char* type, const char* name=nullptr,
|
||||
const char* group=nullptr, const char* doc=nullptr,
|
||||
short attr=0, bool ro=false, bool hidden=false) override;
|
||||
App::Property* addDynamicProperty(const char* type,
|
||||
const char* name = nullptr,
|
||||
const char* group = nullptr,
|
||||
const char* doc = nullptr,
|
||||
short attr = 0,
|
||||
bool ro = false,
|
||||
bool hidden = false) override;
|
||||
|
||||
/** Resolve the last document object referenced in the subname
|
||||
*
|
||||
@@ -502,9 +577,14 @@ public:
|
||||
* @return Returns the last referenced document object in the subname. If no
|
||||
* such object in subname, return pObject.
|
||||
*/
|
||||
App::DocumentObject *resolve(const char *subname, App::DocumentObject **parent=nullptr,
|
||||
std::string *childName=nullptr, const char **subElement=nullptr,
|
||||
PyObject **pyObj=nullptr, Base::Matrix4D *mat=nullptr, bool transform=true, int depth=0) const;
|
||||
App::DocumentObject* resolve(const char* subname,
|
||||
App::DocumentObject** parent = nullptr,
|
||||
std::string* childName = nullptr,
|
||||
const char** subElement = nullptr,
|
||||
PyObject** pyObj = nullptr,
|
||||
Base::Matrix4D* mat = nullptr,
|
||||
bool transform = true,
|
||||
int depth = 0) const;
|
||||
|
||||
/** Resolve a link reference that is relative to this object reference
|
||||
*
|
||||
@@ -550,8 +630,9 @@ public:
|
||||
*
|
||||
* The common parent 'Group' is removed.
|
||||
*/
|
||||
App::DocumentObject *resolveRelativeLink(std::string &subname,
|
||||
App::DocumentObject *&link, std::string &linkSub) const;
|
||||
App::DocumentObject* resolveRelativeLink(std::string& subname,
|
||||
App::DocumentObject*& link,
|
||||
std::string& linkSub) const;
|
||||
|
||||
/** Called to adjust link properties to avoid cyclic links
|
||||
*
|
||||
@@ -567,8 +648,8 @@ public:
|
||||
* properties that can hold subnames) to avoid cyclic when added to the
|
||||
* future parent.
|
||||
*/
|
||||
virtual bool adjustRelativeLinks(const std::set<App::DocumentObject*> &inList,
|
||||
std::set<App::DocumentObject*> *visited=nullptr);
|
||||
virtual bool adjustRelativeLinks(const std::set<App::DocumentObject*>& inList,
|
||||
std::set<App::DocumentObject*>* visited = nullptr);
|
||||
|
||||
/** allow partial loading of dependent objects
|
||||
*
|
||||
@@ -576,9 +657,13 @@ public:
|
||||
* dependent objects to be partially loaded, i.e. only create, but not
|
||||
* restored. 2 means this object itself can be partially loaded.
|
||||
*/
|
||||
virtual int canLoadPartial() const {return 0;}
|
||||
virtual int canLoadPartial() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void onUpdateElementReference(const Property *) {}
|
||||
virtual void onUpdateElementReference(const Property*)
|
||||
{}
|
||||
|
||||
/** Allow object to redirect a subname path
|
||||
*
|
||||
@@ -593,34 +678,34 @@ public:
|
||||
* item is selected in the tree. Document object can use this function to
|
||||
* redirect the selection to some other objects.
|
||||
*/
|
||||
virtual bool redirectSubName(std::ostringstream &ss,
|
||||
DocumentObject *topParent, DocumentObject *child) const;
|
||||
virtual bool
|
||||
redirectSubName(std::ostringstream& ss, DocumentObject* topParent, DocumentObject* child) const;
|
||||
|
||||
/** Special marker to mark the object as hidden
|
||||
*
|
||||
* It is used by Gui::ViewProvider::getElementColors(), but exposed here
|
||||
* for convenience
|
||||
*/
|
||||
static const std::string &hiddenMarker();
|
||||
static const std::string& hiddenMarker();
|
||||
/// Check if the subname reference ends with hidden marker.
|
||||
static const char *hasHiddenMarker(const char *subname);
|
||||
static const char* hasHiddenMarker(const char* subname);
|
||||
|
||||
protected:
|
||||
/// recompute only this object
|
||||
virtual App::DocumentObjectExecReturn *recompute();
|
||||
virtual App::DocumentObjectExecReturn* recompute();
|
||||
/** get called by the document to recompute this feature
|
||||
* Normally this method get called in the processing of
|
||||
* Document::recompute().
|
||||
* In execute() the output properties get recomputed
|
||||
* with the data from linked objects and objects own
|
||||
* properties.
|
||||
*/
|
||||
virtual App::DocumentObjectExecReturn *execute();
|
||||
* Normally this method get called in the processing of
|
||||
* Document::recompute().
|
||||
* In execute() the output properties get recomputed
|
||||
* with the data from linked objects and objects own
|
||||
* properties.
|
||||
*/
|
||||
virtual App::DocumentObjectExecReturn* execute();
|
||||
|
||||
/**
|
||||
* Executes the extensions of a document object.
|
||||
*/
|
||||
App::DocumentObjectExecReturn *executeExtensions();
|
||||
App::DocumentObjectExecReturn* executeExtensions();
|
||||
|
||||
/** Status bits of the document object
|
||||
* The first 8 bits are used for the base system the rest can be used in
|
||||
@@ -638,8 +723,14 @@ protected:
|
||||
*/
|
||||
std::bitset<32> StatusBits;
|
||||
|
||||
void setError(){StatusBits.set(ObjectStatus::Error);}
|
||||
void resetError(){StatusBits.reset(ObjectStatus::Error);}
|
||||
void setError()
|
||||
{
|
||||
StatusBits.set(ObjectStatus::Error);
|
||||
}
|
||||
void resetError()
|
||||
{
|
||||
StatusBits.reset(ObjectStatus::Error);
|
||||
}
|
||||
void setDocument(App::Document* doc);
|
||||
|
||||
/// get called before the value is changed
|
||||
@@ -660,39 +751,40 @@ protected:
|
||||
virtual void unsetupObject();
|
||||
|
||||
/// get called when a property status has changed
|
||||
void onPropertyStatusChanged(const Property &prop, unsigned long oldStatus) override;
|
||||
void onPropertyStatusChanged(const Property& prop, unsigned long oldStatus) override;
|
||||
|
||||
private:
|
||||
void printInvalidLinks() const;
|
||||
|
||||
/// python object of this class and all descendent
|
||||
protected: // attributes
|
||||
/// python object of this class and all descendent
|
||||
protected: // attributes
|
||||
Py::SmartPtr PythonObject;
|
||||
/// pointer to the document this object belongs to
|
||||
App::Document* _pDoc{nullptr};
|
||||
App::Document* _pDoc {nullptr};
|
||||
|
||||
/// Old label; used for renaming expressions
|
||||
std::string oldLabel;
|
||||
|
||||
// pointer to the document name string (for performance)
|
||||
const std::string *pcNameInDocument{nullptr};
|
||||
const std::string* pcNameInDocument {nullptr};
|
||||
|
||||
private:
|
||||
// accessed by App::Document to record and restore the correct view provider type
|
||||
std::string _pcViewProviderName;
|
||||
|
||||
// unique identifier (among a document) of this object.
|
||||
long _Id{0};
|
||||
long _Id {0};
|
||||
|
||||
private:
|
||||
// Back pointer to all the fathers in a DAG of the document
|
||||
// this is used by the document (via friend) to have a effective DAG handling
|
||||
std::vector<App::DocumentObject*> _inList;
|
||||
mutable std::vector<App::DocumentObject *> _outList;
|
||||
mutable std::unordered_map<const char *, App::DocumentObject*, CStringHasher, CStringHasher> _outListMap;
|
||||
mutable std::vector<App::DocumentObject*> _outList;
|
||||
mutable std::unordered_map<const char*, App::DocumentObject*, CStringHasher, CStringHasher>
|
||||
_outListMap;
|
||||
mutable bool _outListCached = false;
|
||||
};
|
||||
|
||||
} //namespace App
|
||||
} // namespace App
|
||||
|
||||
#endif // APP_DOCUMENTOBJECT_H
|
||||
#endif // APP_DOCUMENTOBJECT_H
|
||||
|
||||
+320
-214
@@ -30,7 +30,8 @@
|
||||
#include <Base/Quantity.h>
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
namespace App {
|
||||
namespace App
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expecting the extended expression is going to be constantly amended (to
|
||||
@@ -39,67 +40,87 @@ namespace App {
|
||||
// included by everyone
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct AppExport Expression::Component {
|
||||
struct AppExport Expression::Component
|
||||
{
|
||||
ObjectIdentifier::Component comp;
|
||||
Expression* e1;
|
||||
Expression* e2;
|
||||
Expression* e3;
|
||||
|
||||
explicit Component(const std::string &n);
|
||||
Component(Expression *e1, Expression *e2, Expression *e3, bool isRange=false);
|
||||
explicit Component(const ObjectIdentifier::Component &comp);
|
||||
Component(const Component &other);
|
||||
explicit Component(const std::string& n);
|
||||
Component(Expression* e1, Expression* e2, Expression* e3, bool isRange = false);
|
||||
explicit Component(const ObjectIdentifier::Component& comp);
|
||||
Component(const Component& other);
|
||||
~Component();
|
||||
Component &operator=(const Component &)=delete;
|
||||
Component& operator=(const Component&) = delete;
|
||||
|
||||
void visit(ExpressionVisitor &v);
|
||||
void visit(ExpressionVisitor& v);
|
||||
bool isTouched() const;
|
||||
void toString(std::ostream &ss, bool persistent) const;
|
||||
Component *copy() const;
|
||||
Component *eval() const;
|
||||
void toString(std::ostream& ss, bool persistent) const;
|
||||
Component* copy() const;
|
||||
Component* eval() const;
|
||||
|
||||
Py::Object get(const Expression *owner, const Py::Object &pyobj) const;
|
||||
void set(const Expression *owner, Py::Object &pyobj, const Py::Object &value) const;
|
||||
void del(const Expression *owner, Py::Object &pyobj) const;
|
||||
Py::Object get(const Expression* owner, const Py::Object& pyobj) const;
|
||||
void set(const Expression* owner, Py::Object& pyobj, const Py::Object& value) const;
|
||||
void del(const Expression* owner, Py::Object& pyobj) const;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Part of an expressions that contains a unit.
|
||||
*
|
||||
*/
|
||||
* Part of an expressions that contains a unit.
|
||||
*
|
||||
*/
|
||||
|
||||
class AppExport UnitExpression : public Expression {
|
||||
class AppExport UnitExpression: public Expression
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
explicit UnitExpression(const App::DocumentObject *_owner = nullptr, const Base::Quantity & _quantity = Base::Quantity(), const std::string & _unitStr = std::string());
|
||||
explicit UnitExpression(const App::DocumentObject* _owner = nullptr,
|
||||
const Base::Quantity& _quantity = Base::Quantity(),
|
||||
const std::string& _unitStr = std::string());
|
||||
|
||||
~UnitExpression() override;
|
||||
|
||||
Expression * simplify() const override;
|
||||
Expression* simplify() const override;
|
||||
|
||||
void setUnit(const Base::Quantity &_quantity);
|
||||
void setUnit(const Base::Quantity& _quantity);
|
||||
|
||||
void setQuantity(const Base::Quantity &_quantity);
|
||||
void setQuantity(const Base::Quantity& _quantity);
|
||||
|
||||
double getValue() const { return quantity.getValue(); }
|
||||
double getValue() const
|
||||
{
|
||||
return quantity.getValue();
|
||||
}
|
||||
|
||||
const Base::Unit & getUnit() const { return quantity.getUnit(); }
|
||||
const Base::Unit& getUnit() const
|
||||
{
|
||||
return quantity.getUnit();
|
||||
}
|
||||
|
||||
const Base::Quantity & getQuantity() const { return quantity; }
|
||||
const Base::Quantity& getQuantity() const
|
||||
{
|
||||
return quantity;
|
||||
}
|
||||
|
||||
const std::string getUnitString() const { return unitStr; }
|
||||
const std::string getUnitString() const
|
||||
{
|
||||
return unitStr;
|
||||
}
|
||||
|
||||
double getScaler() const { return quantity.getValue(); }
|
||||
double getScaler() const
|
||||
{
|
||||
return quantity.getValue();
|
||||
}
|
||||
|
||||
protected:
|
||||
Expression * _copy() const override;
|
||||
void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
Expression* _copy() const override;
|
||||
void _toString(std::ostream& ss, bool persistent, int indent) const override;
|
||||
Py::Object _getPyValue() const override;
|
||||
|
||||
protected:
|
||||
mutable PyObject *cache = nullptr;
|
||||
mutable PyObject* cache = nullptr;
|
||||
|
||||
private:
|
||||
Base::Quantity quantity;
|
||||
@@ -107,54 +128,65 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing a number with an optional unit
|
||||
*/
|
||||
* Class implementing a number with an optional unit
|
||||
*/
|
||||
|
||||
class AppExport NumberExpression : public UnitExpression {
|
||||
class AppExport NumberExpression: public UnitExpression
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
public:
|
||||
explicit NumberExpression(const App::DocumentObject *_owner = nullptr, const Base::Quantity & quantity = Base::Quantity());
|
||||
|
||||
Expression * simplify() const override;
|
||||
public:
|
||||
explicit NumberExpression(const App::DocumentObject* _owner = nullptr,
|
||||
const Base::Quantity& quantity = Base::Quantity());
|
||||
|
||||
Expression* simplify() const override;
|
||||
|
||||
void negate();
|
||||
|
||||
bool isInteger(long *v=nullptr) const;
|
||||
bool isInteger(long* v = nullptr) const;
|
||||
|
||||
protected:
|
||||
Expression * _copy() const override;
|
||||
void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
Expression* _copy() const override;
|
||||
void _toString(std::ostream& ss, bool persistent, int indent) const override;
|
||||
};
|
||||
|
||||
class AppExport ConstantExpression : public NumberExpression {
|
||||
class AppExport ConstantExpression: public NumberExpression
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
public:
|
||||
explicit ConstantExpression(const App::DocumentObject *_owner = nullptr,
|
||||
const char *_name = "",
|
||||
const Base::Quantity &_quantity = Base::Quantity());
|
||||
|
||||
std::string getName() const { return name; }
|
||||
public:
|
||||
explicit ConstantExpression(const App::DocumentObject* _owner = nullptr,
|
||||
const char* _name = "",
|
||||
const Base::Quantity& _quantity = Base::Quantity());
|
||||
|
||||
std::string getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
bool isNumber() const;
|
||||
|
||||
protected:
|
||||
Py::Object _getPyValue() const override;
|
||||
void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
void _toString(std::ostream& ss, bool persistent, int indent) const override;
|
||||
Expression* _copy() const override;
|
||||
|
||||
protected:
|
||||
const char *name;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing an infix expression.
|
||||
*
|
||||
*/
|
||||
* Class implementing an infix expression.
|
||||
*
|
||||
*/
|
||||
|
||||
class AppExport OperatorExpression : public UnitExpression {
|
||||
class AppExport OperatorExpression: public UnitExpression
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
enum Operator {
|
||||
enum Operator
|
||||
{
|
||||
NONE,
|
||||
ADD,
|
||||
SUB,
|
||||
@@ -172,30 +204,42 @@ public:
|
||||
NEG,
|
||||
POS
|
||||
};
|
||||
explicit OperatorExpression(const App::DocumentObject *_owner = nullptr, Expression * _left = nullptr, Operator _op = NONE, Expression * _right = nullptr);
|
||||
explicit OperatorExpression(const App::DocumentObject* _owner = nullptr,
|
||||
Expression* _left = nullptr,
|
||||
Operator _op = NONE,
|
||||
Expression* _right = nullptr);
|
||||
|
||||
~OperatorExpression() override;
|
||||
|
||||
bool isTouched() const override;
|
||||
|
||||
Expression * simplify() const override;
|
||||
Expression* simplify() const override;
|
||||
|
||||
int priority() const override;
|
||||
|
||||
Operator getOperator() const { return op; }
|
||||
Operator getOperator() const
|
||||
{
|
||||
return op;
|
||||
}
|
||||
|
||||
Expression * getLeft() const { return left; }
|
||||
Expression* getLeft() const
|
||||
{
|
||||
return left;
|
||||
}
|
||||
|
||||
Expression * getRight() const { return right; }
|
||||
Expression* getRight() const
|
||||
{
|
||||
return right;
|
||||
}
|
||||
|
||||
protected:
|
||||
Expression * _copy() const override;
|
||||
Expression* _copy() const override;
|
||||
|
||||
Py::Object _getPyValue() const override;
|
||||
|
||||
void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
void _toString(std::ostream& ss, bool persistent, int indent) const override;
|
||||
|
||||
void _visit(ExpressionVisitor & v) override;
|
||||
void _visit(ExpressionVisitor& v) override;
|
||||
|
||||
virtual bool isCommutative() const;
|
||||
|
||||
@@ -203,46 +247,53 @@ protected:
|
||||
|
||||
virtual bool isRightAssociative() const;
|
||||
|
||||
Operator op; /**< Operator working on left and right */
|
||||
Expression * left; /**< Left operand */
|
||||
Expression * right; /**< Right operand */
|
||||
Operator op; /**< Operator working on left and right */
|
||||
Expression* left; /**< Left operand */
|
||||
Expression* right; /**< Right operand */
|
||||
};
|
||||
|
||||
class AppExport ConditionalExpression : public Expression {
|
||||
class AppExport ConditionalExpression: public Expression
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
explicit ConditionalExpression(const App::DocumentObject *_owner = nullptr, Expression * _condition = nullptr,Expression * _trueExpr = nullptr, Expression * _falseExpr = nullptr);
|
||||
explicit ConditionalExpression(const App::DocumentObject* _owner = nullptr,
|
||||
Expression* _condition = nullptr,
|
||||
Expression* _trueExpr = nullptr,
|
||||
Expression* _falseExpr = nullptr);
|
||||
|
||||
~ConditionalExpression() override;
|
||||
|
||||
bool isTouched() const override;
|
||||
|
||||
Expression * simplify() const override;
|
||||
Expression* simplify() const override;
|
||||
|
||||
int priority() const override;
|
||||
|
||||
protected:
|
||||
Expression * _copy() const override;
|
||||
void _visit(ExpressionVisitor & v) override;
|
||||
void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
Expression* _copy() const override;
|
||||
void _visit(ExpressionVisitor& v) override;
|
||||
void _toString(std::ostream& ss, bool persistent, int indent) const override;
|
||||
Py::Object _getPyValue() const override;
|
||||
|
||||
protected:
|
||||
|
||||
Expression * condition; /**< Condition */
|
||||
Expression * trueExpr; /**< Expression if abs(condition) is > 0.5 */
|
||||
Expression * falseExpr; /**< Expression if abs(condition) is < 0.5 */
|
||||
Expression* condition; /**< Condition */
|
||||
Expression* trueExpr; /**< Expression if abs(condition) is > 0.5 */
|
||||
Expression* falseExpr; /**< Expression if abs(condition) is < 0.5 */
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing various functions, e.g sin, cos, etc.
|
||||
*
|
||||
*/
|
||||
* Class implementing various functions, e.g sin, cos, etc.
|
||||
*
|
||||
*/
|
||||
|
||||
class AppExport FunctionExpression : public UnitExpression {
|
||||
class AppExport FunctionExpression: public UnitExpression
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
enum Function {
|
||||
enum Function
|
||||
{
|
||||
NONE,
|
||||
|
||||
// Normal functions taking one or two arguments
|
||||
@@ -287,31 +338,32 @@ public:
|
||||
VSCALEZ,
|
||||
|
||||
// Matrix
|
||||
MINVERT, // invert matrix/placement/rotation
|
||||
MROTATE, // Rotate matrix/placement/rotation around axis, by rotation object, or by euler angles.
|
||||
MROTATEX, // Rotate matrix/placement/rotation around x-axis.
|
||||
MROTATEY, // Rotate matrix/placement/rotation around y-axis.
|
||||
MROTATEZ, // Rotate matrix/placement/rotation around z-axis.
|
||||
MSCALE, // matrix scale by vector
|
||||
MTRANSLATE, // Translate matrix/placement.
|
||||
MINVERT, // invert matrix/placement/rotation
|
||||
MROTATE, // Rotate matrix/placement/rotation around axis, by rotation object, or by euler
|
||||
// angles.
|
||||
MROTATEX, // Rotate matrix/placement/rotation around x-axis.
|
||||
MROTATEY, // Rotate matrix/placement/rotation around y-axis.
|
||||
MROTATEZ, // Rotate matrix/placement/rotation around z-axis.
|
||||
MSCALE, // matrix scale by vector
|
||||
MTRANSLATE, // Translate matrix/placement.
|
||||
|
||||
// Object creation
|
||||
CREATE, // Create new object of a given type.
|
||||
LIST, // Create Python list.
|
||||
MATRIX, // Create matrix object.
|
||||
PLACEMENT, // Create placement object.
|
||||
ROTATION, // Create rotation object.
|
||||
ROTATIONX, // Create x-axis rotation object.
|
||||
ROTATIONY, // Create y-axis rotation object.
|
||||
ROTATIONZ, // Create z-axis rotation object.
|
||||
STR, // stringify
|
||||
PARSEQUANT, // parse string quantity
|
||||
TRANSLATIONM, // Create translation matrix object.
|
||||
TUPLE, // Create Python tuple.
|
||||
VECTOR, // Create vector object.
|
||||
CREATE, // Create new object of a given type.
|
||||
LIST, // Create Python list.
|
||||
MATRIX, // Create matrix object.
|
||||
PLACEMENT, // Create placement object.
|
||||
ROTATION, // Create rotation object.
|
||||
ROTATIONX, // Create x-axis rotation object.
|
||||
ROTATIONY, // Create y-axis rotation object.
|
||||
ROTATIONZ, // Create z-axis rotation object.
|
||||
STR, // stringify
|
||||
PARSEQUANT, // parse string quantity
|
||||
TRANSLATIONM, // Create translation matrix object.
|
||||
TUPLE, // Create Python tuple.
|
||||
VECTOR, // Create vector object.
|
||||
|
||||
HIDDENREF, // hidden reference that has no dependency check
|
||||
HREF, // deprecated alias of HIDDENREF
|
||||
HIDDENREF, // hidden reference that has no dependency check
|
||||
HREF, // deprecated alias of HIDDENREF
|
||||
|
||||
// Aggregates
|
||||
AGGREGATES,
|
||||
@@ -327,219 +379,273 @@ public:
|
||||
LAST,
|
||||
};
|
||||
|
||||
explicit FunctionExpression(const App::DocumentObject *_owner = nullptr, Function _f = NONE,
|
||||
std::string &&name = std::string(), std::vector<Expression *> _args = std::vector<Expression*>());
|
||||
explicit FunctionExpression(const App::DocumentObject* _owner = nullptr,
|
||||
Function _f = NONE,
|
||||
std::string&& name = std::string(),
|
||||
std::vector<Expression*> _args = std::vector<Expression*>());
|
||||
|
||||
~FunctionExpression() override;
|
||||
|
||||
bool isTouched() const override;
|
||||
|
||||
Expression * simplify() const override;
|
||||
Expression* simplify() const override;
|
||||
|
||||
static Py::Object evaluate(const Expression *owner, int type, const std::vector<Expression*> &args);
|
||||
static Py::Object
|
||||
evaluate(const Expression* owner, int type, const std::vector<Expression*>& args);
|
||||
|
||||
Function getFunction() const {return f;}
|
||||
const std::vector<Expression*> &getArgs() const {return args;}
|
||||
Function getFunction() const
|
||||
{
|
||||
return f;
|
||||
}
|
||||
const std::vector<Expression*>& getArgs() const
|
||||
{
|
||||
return args;
|
||||
}
|
||||
|
||||
protected:
|
||||
static Py::Object evalAggregate(const Expression *owner, int type, const std::vector<Expression*> &args);
|
||||
static Base::Vector3d evaluateSecondVectorArgument(const Expression *expression, const std::vector<Expression*> &arguments);
|
||||
static double extractLengthValueArgument(const Expression *expression, const std::vector<Expression*> &arguments, int argumentIndex);
|
||||
static Base::Vector3d extractVectorArgument(const Expression *expression, const std::vector<Expression*> &arguments, int argumentIndex);
|
||||
static void initialiseObject(const Py::Object *object, const std::vector<Expression*> &arguments, const unsigned long offset = 0);
|
||||
static Py::Object transformFirstArgument(
|
||||
const Expression *expression,
|
||||
const std::vector<Expression*> &arguments,
|
||||
const Base::Matrix4D *transformationMatrix);
|
||||
static Py::Object
|
||||
evalAggregate(const Expression* owner, int type, const std::vector<Expression*>& args);
|
||||
static Base::Vector3d evaluateSecondVectorArgument(const Expression* expression,
|
||||
const std::vector<Expression*>& arguments);
|
||||
static double extractLengthValueArgument(const Expression* expression,
|
||||
const std::vector<Expression*>& arguments,
|
||||
int argumentIndex);
|
||||
static Base::Vector3d extractVectorArgument(const Expression* expression,
|
||||
const std::vector<Expression*>& arguments,
|
||||
int argumentIndex);
|
||||
static void initialiseObject(const Py::Object* object,
|
||||
const std::vector<Expression*>& arguments,
|
||||
const unsigned long offset = 0);
|
||||
static Py::Object transformFirstArgument(const Expression* expression,
|
||||
const std::vector<Expression*>& arguments,
|
||||
const Base::Matrix4D* transformationMatrix);
|
||||
static Py::Object translationMatrix(double x, double y, double z);
|
||||
Py::Object _getPyValue() const override;
|
||||
Expression * _copy() const override;
|
||||
void _visit(ExpressionVisitor & v) override;
|
||||
void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
Expression* _copy() const override;
|
||||
void _visit(ExpressionVisitor& v) override;
|
||||
void _toString(std::ostream& ss, bool persistent, int indent) const override;
|
||||
|
||||
Function f; /**< Function to execute */
|
||||
Function f; /**< Function to execute */
|
||||
std::string fname;
|
||||
std::vector<Expression *> args; /** Arguments to function*/
|
||||
std::vector<Expression*> args; /** Arguments to function*/
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing a reference to a property. If the name is unqualified,
|
||||
* the owner of the expression is searched. If it is qualified, the document
|
||||
* that contains the owning document object is searched for other document
|
||||
* objects to search. Both labels and internal document names are searched.
|
||||
*
|
||||
*/
|
||||
* Class implementing a reference to a property. If the name is unqualified,
|
||||
* the owner of the expression is searched. If it is qualified, the document
|
||||
* that contains the owning document object is searched for other document
|
||||
* objects to search. Both labels and internal document names are searched.
|
||||
*
|
||||
*/
|
||||
|
||||
class AppExport VariableExpression : public UnitExpression {
|
||||
class AppExport VariableExpression: public UnitExpression
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
explicit VariableExpression(const App::DocumentObject *_owner = nullptr, const ObjectIdentifier& _var = ObjectIdentifier());
|
||||
explicit VariableExpression(const App::DocumentObject* _owner = nullptr,
|
||||
const ObjectIdentifier& _var = ObjectIdentifier());
|
||||
|
||||
~VariableExpression() override;
|
||||
|
||||
bool isTouched() const override;
|
||||
|
||||
Expression * simplify() const override;
|
||||
Expression* simplify() const override;
|
||||
|
||||
std::string name() const { return var.getPropertyName(); }
|
||||
std::string name() const
|
||||
{
|
||||
return var.getPropertyName();
|
||||
}
|
||||
|
||||
ObjectIdentifier getPath() const { return var; }
|
||||
ObjectIdentifier getPath() const
|
||||
{
|
||||
return var;
|
||||
}
|
||||
|
||||
void setPath(const ObjectIdentifier & path);
|
||||
void setPath(const ObjectIdentifier& path);
|
||||
|
||||
const App::Property *getProperty() const;
|
||||
const App::Property* getProperty() const;
|
||||
|
||||
void addComponent(Component* component) override;
|
||||
|
||||
protected:
|
||||
Expression * _copy() const override;
|
||||
Expression* _copy() const override;
|
||||
Py::Object _getPyValue() const override;
|
||||
void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
void _toString(std::ostream& ss, bool persistent, int indent) const override;
|
||||
bool _isIndexable() const override;
|
||||
void _getIdentifiers(std::map<App::ObjectIdentifier,bool> &) const override;
|
||||
bool _adjustLinks(const std::set<App::DocumentObject*> &, ExpressionVisitor &) override;
|
||||
void _importSubNames(const ObjectIdentifier::SubNameMap &) override;
|
||||
void _updateLabelReference(App::DocumentObject *, const std::string &, const char *) override;
|
||||
bool _updateElementReference(App::DocumentObject *,bool,ExpressionVisitor &) override;
|
||||
bool _relabeledDocument(const std::string &, const std::string &, ExpressionVisitor &) override;
|
||||
bool _renameObjectIdentifier(const std::map<ObjectIdentifier,ObjectIdentifier> &,
|
||||
const ObjectIdentifier &, ExpressionVisitor &) override;
|
||||
void _collectReplacement(std::map<ObjectIdentifier,ObjectIdentifier> &,
|
||||
const App::DocumentObject *parent, App::DocumentObject *oldObj,
|
||||
App::DocumentObject *newObj) const override;
|
||||
void _moveCells(const CellAddress &, int, int, ExpressionVisitor &) override;
|
||||
void _offsetCells(int, int, ExpressionVisitor &) override;
|
||||
void _getIdentifiers(std::map<App::ObjectIdentifier, bool>&) const override;
|
||||
bool _adjustLinks(const std::set<App::DocumentObject*>&, ExpressionVisitor&) override;
|
||||
void _importSubNames(const ObjectIdentifier::SubNameMap&) override;
|
||||
void _updateLabelReference(App::DocumentObject*, const std::string&, const char*) override;
|
||||
bool _updateElementReference(App::DocumentObject*, bool, ExpressionVisitor&) override;
|
||||
bool _relabeledDocument(const std::string&, const std::string&, ExpressionVisitor&) override;
|
||||
bool _renameObjectIdentifier(const std::map<ObjectIdentifier, ObjectIdentifier>&,
|
||||
const ObjectIdentifier&,
|
||||
ExpressionVisitor&) override;
|
||||
void _collectReplacement(std::map<ObjectIdentifier, ObjectIdentifier>&,
|
||||
const App::DocumentObject* parent,
|
||||
App::DocumentObject* oldObj,
|
||||
App::DocumentObject* newObj) const override;
|
||||
void _moveCells(const CellAddress&, int, int, ExpressionVisitor&) override;
|
||||
void _offsetCells(int, int, ExpressionVisitor&) override;
|
||||
|
||||
protected:
|
||||
|
||||
ObjectIdentifier var; /**< Variable name */
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class AppExport PyObjectExpression : public Expression {
|
||||
class AppExport PyObjectExpression: public Expression
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
explicit PyObjectExpression(const App::DocumentObject *_owner=nullptr, PyObject *pyobj=nullptr, bool owned=false)
|
||||
:Expression(_owner)
|
||||
explicit PyObjectExpression(const App::DocumentObject* _owner = nullptr,
|
||||
PyObject* pyobj = nullptr,
|
||||
bool owned = false)
|
||||
: Expression(_owner)
|
||||
{
|
||||
setPyValue(pyobj,owned);
|
||||
setPyValue(pyobj, owned);
|
||||
}
|
||||
|
||||
~PyObjectExpression() override;
|
||||
|
||||
void setPyValue(Py::Object pyobj);
|
||||
void setPyValue(PyObject *pyobj, bool owned=false);
|
||||
Expression * simplify() const override { return copy(); }
|
||||
void setPyValue(PyObject* pyobj, bool owned = false);
|
||||
Expression* simplify() const override
|
||||
{
|
||||
return copy();
|
||||
}
|
||||
|
||||
protected:
|
||||
Expression* _copy() const override;
|
||||
void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
void _toString(std::ostream& ss, bool persistent, int indent) const override;
|
||||
Py::Object _getPyValue() const override;
|
||||
|
||||
protected:
|
||||
PyObject *pyObj = nullptr;
|
||||
PyObject* pyObj = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing a string. Used to signal either a genuine string or
|
||||
* a failed evaluation of an expression.
|
||||
*/
|
||||
* Class implementing a string. Used to signal either a genuine string or
|
||||
* a failed evaluation of an expression.
|
||||
*/
|
||||
|
||||
class AppExport StringExpression : public Expression {
|
||||
class AppExport StringExpression: public Expression
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
explicit StringExpression(const App::DocumentObject *_owner = nullptr, const std::string & _text = std::string());
|
||||
explicit StringExpression(const App::DocumentObject* _owner = nullptr,
|
||||
const std::string& _text = std::string());
|
||||
~StringExpression() override;
|
||||
|
||||
Expression * simplify() const override;
|
||||
Expression* simplify() const override;
|
||||
|
||||
virtual std::string getText() const
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
virtual std::string getText() const { return text; }
|
||||
protected:
|
||||
Expression * _copy() const override;
|
||||
void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
Expression* _copy() const override;
|
||||
void _toString(std::ostream& ss, bool persistent, int indent) const override;
|
||||
Py::Object _getPyValue() const override;
|
||||
bool _isIndexable() const override { return true; }
|
||||
bool _isIndexable() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string text; /**< Text string */
|
||||
mutable PyObject *cache = nullptr;
|
||||
mutable PyObject* cache = nullptr;
|
||||
};
|
||||
|
||||
class AppExport RangeExpression : public App::Expression {
|
||||
class AppExport RangeExpression: public App::Expression
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
explicit RangeExpression(const App::DocumentObject * _owner = nullptr, const std::string & begin = std::string(), const std::string & end = std::string());
|
||||
explicit RangeExpression(const App::DocumentObject* _owner = nullptr,
|
||||
const std::string& begin = std::string(),
|
||||
const std::string& end = std::string());
|
||||
|
||||
~RangeExpression() override = default;
|
||||
|
||||
bool isTouched() const override;
|
||||
|
||||
App::Expression * simplify() const override;
|
||||
App::Expression* simplify() const override;
|
||||
|
||||
Range getRange() const;
|
||||
|
||||
protected:
|
||||
Expression * _copy() const override;
|
||||
void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
Expression* _copy() const override;
|
||||
void _toString(std::ostream& ss, bool persistent, int indent) const override;
|
||||
Py::Object _getPyValue() const override;
|
||||
void _getIdentifiers(std::map<App::ObjectIdentifier,bool> &) const override;
|
||||
bool _renameObjectIdentifier(const std::map<ObjectIdentifier,ObjectIdentifier> &,
|
||||
const ObjectIdentifier &, ExpressionVisitor &) override;
|
||||
void _moveCells(const CellAddress &, int, int, ExpressionVisitor &) override;
|
||||
void _offsetCells(int, int, ExpressionVisitor &) override;
|
||||
void _getIdentifiers(std::map<App::ObjectIdentifier, bool>&) const override;
|
||||
bool _renameObjectIdentifier(const std::map<ObjectIdentifier, ObjectIdentifier>&,
|
||||
const ObjectIdentifier&,
|
||||
ExpressionVisitor&) override;
|
||||
void _moveCells(const CellAddress&, int, int, ExpressionVisitor&) override;
|
||||
void _offsetCells(int, int, ExpressionVisitor&) override;
|
||||
|
||||
protected:
|
||||
std::string begin;
|
||||
std::string end;
|
||||
};
|
||||
|
||||
namespace ExpressionParser {
|
||||
AppExport Expression * parse(const App::DocumentObject *owner, const char *buffer);
|
||||
AppExport UnitExpression * parseUnit(const App::DocumentObject *owner, const char *buffer);
|
||||
AppExport ObjectIdentifier parsePath(const App::DocumentObject *owner, const char* buffer);
|
||||
AppExport bool isTokenAnIndentifier(const std::string & str);
|
||||
AppExport bool isTokenAConstant(const std::string & str);
|
||||
AppExport bool isTokenAUnit(const std::string & str);
|
||||
AppExport std::vector<std::tuple<int, int, std::string> > tokenize(const std::string & str);
|
||||
namespace ExpressionParser
|
||||
{
|
||||
AppExport Expression* parse(const App::DocumentObject* owner, const char* buffer);
|
||||
AppExport UnitExpression* parseUnit(const App::DocumentObject* owner, const char* buffer);
|
||||
AppExport ObjectIdentifier parsePath(const App::DocumentObject* owner, const char* buffer);
|
||||
AppExport bool isTokenAnIndentifier(const std::string& str);
|
||||
AppExport bool isTokenAConstant(const std::string& str);
|
||||
AppExport bool isTokenAUnit(const std::string& str);
|
||||
AppExport std::vector<std::tuple<int, int, std::string>> tokenize(const std::string& str);
|
||||
|
||||
/// Convenient class to mark begin of importing
|
||||
class AppExport ExpressionImporter {
|
||||
class AppExport ExpressionImporter
|
||||
{
|
||||
public:
|
||||
explicit ExpressionImporter(Base::XMLReader &reader);
|
||||
explicit ExpressionImporter(Base::XMLReader& reader);
|
||||
~ExpressionImporter();
|
||||
static Base::XMLReader *reader();
|
||||
static Base::XMLReader* reader();
|
||||
};
|
||||
|
||||
AppExport bool isModuleImported(PyObject *);
|
||||
AppExport bool isModuleImported(PyObject*);
|
||||
|
||||
/**
|
||||
* @brief The semantic_type class encapsulates the value in the parse tree during parsing.
|
||||
*/
|
||||
|
||||
class semantic_type {
|
||||
class semantic_type
|
||||
{
|
||||
public:
|
||||
struct {
|
||||
Base::Quantity scaler;
|
||||
std::string unitStr;
|
||||
} quantity;
|
||||
Expression::Component *component{nullptr};
|
||||
Expression * expr{nullptr};
|
||||
ObjectIdentifier path;
|
||||
std::deque<ObjectIdentifier::Component> components;
|
||||
long long int ivalue{0};
|
||||
double fvalue{0};
|
||||
struct {
|
||||
const char *name = "";
|
||||
double fvalue = 0;
|
||||
} constant;
|
||||
std::vector<Expression*> arguments;
|
||||
std::vector<Expression*> list;
|
||||
std::string string;
|
||||
std::pair<FunctionExpression::Function,std::string> func;
|
||||
ObjectIdentifier::String string_or_identifier;
|
||||
semantic_type() : func({FunctionExpression::NONE, std::string()}) {}
|
||||
struct
|
||||
{
|
||||
Base::Quantity scaler;
|
||||
std::string unitStr;
|
||||
} quantity;
|
||||
Expression::Component* component {nullptr};
|
||||
Expression* expr {nullptr};
|
||||
ObjectIdentifier path;
|
||||
std::deque<ObjectIdentifier::Component> components;
|
||||
long long int ivalue {0};
|
||||
double fvalue {0};
|
||||
struct
|
||||
{
|
||||
const char* name = "";
|
||||
double fvalue = 0;
|
||||
} constant;
|
||||
std::vector<Expression*> arguments;
|
||||
std::vector<Expression*> list;
|
||||
std::string string;
|
||||
std::pair<FunctionExpression::Function, std::string> func;
|
||||
ObjectIdentifier::String string_or_identifier;
|
||||
semantic_type()
|
||||
: func({FunctionExpression::NONE, std::string()})
|
||||
{}
|
||||
};
|
||||
|
||||
#define YYSTYPE semantic_type
|
||||
@@ -547,8 +653,8 @@ public:
|
||||
#undef YYTOKENTYPE
|
||||
#undef YYSTYPE
|
||||
#undef YYSTYPE_ISDECLARED
|
||||
}
|
||||
} // namespace ExpressionParser
|
||||
|
||||
}
|
||||
} // namespace App
|
||||
|
||||
#endif //EXPRESSION_PARSER_H
|
||||
#endif // EXPRESSION_PARSER_H
|
||||
|
||||
@@ -44,16 +44,16 @@ QString ExpressionTokenizer::perform(const QString& prefix, int pos)
|
||||
std::vector<std::tuple<int, int, std::string>> result =
|
||||
ExpressionParser::tokenize(expr.toStdString());
|
||||
std::vector<std::tuple<int, int, QString>> tokens;
|
||||
std::transform(result.cbegin(),
|
||||
result.cend(),
|
||||
std::back_inserter(tokens),
|
||||
[&](const std::tuple<int, int, std::string>& item) {
|
||||
return std::make_tuple(
|
||||
std::get<0>(item),
|
||||
QString::fromStdString(expr.toStdString().substr(0, std::get<1>(item))).size(),
|
||||
QString::fromStdString(std::get<2>(item))
|
||||
);
|
||||
});
|
||||
std::transform(
|
||||
result.cbegin(),
|
||||
result.cend(),
|
||||
std::back_inserter(tokens),
|
||||
[&](const std::tuple<int, int, std::string>& item) {
|
||||
return std::make_tuple(
|
||||
std::get<0>(item),
|
||||
QString::fromStdString(expr.toStdString().substr(0, std::get<1>(item))).size(),
|
||||
QString::fromStdString(std::get<2>(item)));
|
||||
});
|
||||
return tokens;
|
||||
};
|
||||
|
||||
@@ -63,7 +63,7 @@ QString ExpressionTokenizer::perform(const QString& prefix, int pos)
|
||||
int start = (prefix.size() > 0 && prefix.at(0) == QChar::fromLatin1('=')) ? 1 : 0;
|
||||
|
||||
// Tokenize prefix
|
||||
std::vector<std::tuple<int, int, QString> > tokens = tokenizeExpression(prefix.mid(start));
|
||||
std::vector<std::tuple<int, int, QString>> tokens = tokenizeExpression(prefix.mid(start));
|
||||
|
||||
// No tokens
|
||||
if (tokens.empty()) {
|
||||
@@ -78,8 +78,9 @@ QString ExpressionTokenizer::perform(const QString& prefix, int pos)
|
||||
if (std::get<1>(*it) >= pos) {
|
||||
// Include the immediately followed '.' or '#', because we'll be
|
||||
// inserting these separators too, in ExpressionCompleteModel::pathFromIndex()
|
||||
if (it != tokens.begin() && std::get<0>(*it) != '.' && std::get<0>(*it) != '#')
|
||||
if (it != tokens.begin() && std::get<0>(*it) != '.' && std::get<0>(*it) != '#') {
|
||||
it = it - 1;
|
||||
}
|
||||
tokens.resize(it - tokens.begin() + 1);
|
||||
prefixEnd = start + std::get<1>(*it) + (int)std::get<2>(*it).size();
|
||||
break;
|
||||
@@ -87,8 +88,9 @@ QString ExpressionTokenizer::perform(const QString& prefix, int pos)
|
||||
}
|
||||
|
||||
int trim = 0;
|
||||
if (prefixEnd > pos)
|
||||
if (prefixEnd > pos) {
|
||||
trim = prefixEnd - pos;
|
||||
}
|
||||
|
||||
// Extract last tokens that can be rebuilt to a variable
|
||||
long i = static_cast<long>(tokens.size()) - 1;
|
||||
@@ -111,9 +113,8 @@ QString ExpressionTokenizer::perform(const QString& prefix, int pos)
|
||||
}
|
||||
|
||||
// Not an unclosed string and the last character is a space
|
||||
if (!stringing && !prefix.isEmpty() &&
|
||||
prefixEnd > 0 && prefixEnd <= prefix.size() &&
|
||||
prefix[prefixEnd-1] == QChar(32)) {
|
||||
if (!stringing && !prefix.isEmpty() && prefixEnd > 0 && prefixEnd <= prefix.size()
|
||||
&& prefix[prefixEnd - 1] == QChar(32)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -121,23 +122,22 @@ QString ExpressionTokenizer::perform(const QString& prefix, int pos)
|
||||
i = static_cast<long>(tokens.size()) - 1;
|
||||
for (; i >= 0; --i) {
|
||||
int token = std::get<0>(tokens[i]);
|
||||
if (token != '.' &&
|
||||
token != '#' &&
|
||||
token != ExpressionParser::IDENTIFIER &&
|
||||
token != ExpressionParser::INTEGER &&
|
||||
token != ExpressionParser::STRING &&
|
||||
token != ExpressionParser::UNIT &&
|
||||
token != ExpressionParser::ONE)
|
||||
if (token != '.' && token != '#' && token != ExpressionParser::IDENTIFIER
|
||||
&& token != ExpressionParser::INTEGER && token != ExpressionParser::STRING
|
||||
&& token != ExpressionParser::UNIT && token != ExpressionParser::ONE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
// Set prefix start for use when replacing later
|
||||
if (i == static_cast<long>(tokens.size()))
|
||||
if (i == static_cast<long>(tokens.size())) {
|
||||
prefixStart = prefixEnd;
|
||||
else
|
||||
}
|
||||
else {
|
||||
prefixStart = start + std::get<1>(tokens[i]);
|
||||
}
|
||||
|
||||
// Build prefix from tokens
|
||||
while (i < static_cast<long>(tokens.size())) {
|
||||
@@ -145,8 +145,9 @@ QString ExpressionTokenizer::perform(const QString& prefix, int pos)
|
||||
++i;
|
||||
}
|
||||
|
||||
if (trim && trim < int(completionPrefix.size()))
|
||||
if (trim && trim < int(completionPrefix.size())) {
|
||||
completionPrefix.resize(completionPrefix.size() - trim);
|
||||
}
|
||||
|
||||
return completionPrefix;
|
||||
}
|
||||
|
||||
@@ -34,12 +34,14 @@ class AppExport ExpressionTokenizer
|
||||
public:
|
||||
QString perform(const QString& text, int pos);
|
||||
|
||||
void getPrefixRange(int &start, int &end) const {
|
||||
void getPrefixRange(int& start, int& end) const
|
||||
{
|
||||
start = prefixStart;
|
||||
end = prefixEnd;
|
||||
}
|
||||
|
||||
void updatePrefixEnd(int end) {
|
||||
void updatePrefixEnd(int end)
|
||||
{
|
||||
prefixEnd = end;
|
||||
}
|
||||
|
||||
@@ -48,6 +50,6 @@ private:
|
||||
int prefixEnd = 0;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace App
|
||||
|
||||
#endif //EXPRESSIONTOKENIZER_H
|
||||
#endif // EXPRESSIONTOKENIZER_H
|
||||
|
||||
@@ -25,48 +25,57 @@
|
||||
|
||||
#include "Expression.h"
|
||||
|
||||
namespace App {
|
||||
namespace App
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief The RenameObjectIdentifierExpressionVisitor class is a functor used to visit each node of an expression, and
|
||||
* possibly rename VariableExpression nodes.
|
||||
* @brief The RenameObjectIdentifierExpressionVisitor class is a functor used to visit each node of
|
||||
* an expression, and possibly rename VariableExpression nodes.
|
||||
*/
|
||||
|
||||
template<class P> class RenameObjectIdentifierExpressionVisitor : public ExpressionModifier<P> {
|
||||
template<class P>
|
||||
class RenameObjectIdentifierExpressionVisitor: public ExpressionModifier<P>
|
||||
{
|
||||
public:
|
||||
RenameObjectIdentifierExpressionVisitor(
|
||||
P &_prop,
|
||||
const std::map<ObjectIdentifier, ObjectIdentifier> &_paths,
|
||||
const ObjectIdentifier &_owner)
|
||||
P& _prop,
|
||||
const std::map<ObjectIdentifier, ObjectIdentifier>& _paths,
|
||||
const ObjectIdentifier& _owner)
|
||||
: ExpressionModifier<P>(_prop)
|
||||
, paths( _paths )
|
||||
, owner( _owner )
|
||||
{
|
||||
}
|
||||
, paths(_paths)
|
||||
, owner(_owner)
|
||||
{}
|
||||
|
||||
void visit(Expression &node) override {
|
||||
this->renameObjectIdentifier(node,paths,owner);
|
||||
void visit(Expression& node) override
|
||||
{
|
||||
this->renameObjectIdentifier(node, paths, owner);
|
||||
}
|
||||
|
||||
private:
|
||||
const std::map<ObjectIdentifier, ObjectIdentifier> &paths; /**< Map with current and new object identifiers */
|
||||
const ObjectIdentifier owner; /**< Owner of expression */
|
||||
const std::map<ObjectIdentifier, ObjectIdentifier>&
|
||||
paths; /**< Map with current and new object identifiers */
|
||||
const ObjectIdentifier owner; /**< Owner of expression */
|
||||
};
|
||||
|
||||
template<class P> class UpdateElementReferenceExpressionVisitor : public ExpressionModifier<P> {
|
||||
template<class P>
|
||||
class UpdateElementReferenceExpressionVisitor: public ExpressionModifier<P>
|
||||
{
|
||||
public:
|
||||
explicit UpdateElementReferenceExpressionVisitor(P& _prop,
|
||||
App::DocumentObject* feature = nullptr,
|
||||
bool reverse = false)
|
||||
: ExpressionModifier<P>(_prop)
|
||||
, feature(feature)
|
||||
, reverse(reverse)
|
||||
{}
|
||||
|
||||
explicit UpdateElementReferenceExpressionVisitor(P & _prop, App::DocumentObject *feature=nullptr, bool reverse=false)
|
||||
: ExpressionModifier<P>(_prop),feature(feature),reverse(reverse)
|
||||
void visit(Expression& node) override
|
||||
{
|
||||
}
|
||||
|
||||
void visit(Expression &node) override {
|
||||
this->updateElementReference(node,feature,reverse);
|
||||
this->updateElementReference(node, feature, reverse);
|
||||
}
|
||||
|
||||
private:
|
||||
App::DocumentObject *feature;
|
||||
App::DocumentObject* feature;
|
||||
bool reverse;
|
||||
};
|
||||
|
||||
@@ -74,30 +83,36 @@ private:
|
||||
// ExpressionModifier, hence not calling aboutToSetValue/hasSetValue().
|
||||
// By right, modification of document label should not change evaluation result
|
||||
// of any expression.
|
||||
class RelabelDocumentExpressionVisitor : public ExpressionVisitor {
|
||||
class RelabelDocumentExpressionVisitor: public ExpressionVisitor
|
||||
{
|
||||
public:
|
||||
explicit RelabelDocumentExpressionVisitor(const App::Document& doc)
|
||||
: doc(doc)
|
||||
{}
|
||||
|
||||
explicit RelabelDocumentExpressionVisitor(const App::Document &doc)
|
||||
: doc(doc)
|
||||
void visit(Expression& node) override
|
||||
{
|
||||
}
|
||||
|
||||
void visit(Expression &node) override {
|
||||
this->relabeledDocument(node,doc.getOldLabel(),doc.Label.getStrValue());
|
||||
this->relabeledDocument(node, doc.getOldLabel(), doc.Label.getStrValue());
|
||||
}
|
||||
|
||||
private:
|
||||
const App::Document &doc;
|
||||
const App::Document& doc;
|
||||
};
|
||||
|
||||
template<class P> class MoveCellsExpressionVisitor : public ExpressionModifier<P> {
|
||||
template<class P>
|
||||
class MoveCellsExpressionVisitor: public ExpressionModifier<P>
|
||||
{
|
||||
public:
|
||||
MoveCellsExpressionVisitor(P &prop, const CellAddress &address, int rowCount, int colCount)
|
||||
: ExpressionModifier<P>(prop),address(address),rowCount(rowCount),colCount(colCount)
|
||||
MoveCellsExpressionVisitor(P& prop, const CellAddress& address, int rowCount, int colCount)
|
||||
: ExpressionModifier<P>(prop)
|
||||
, address(address)
|
||||
, rowCount(rowCount)
|
||||
, colCount(colCount)
|
||||
{}
|
||||
|
||||
void visit(Expression &node) override {
|
||||
this->moveCells(node,address,rowCount,colCount);
|
||||
void visit(Expression& node) override
|
||||
{
|
||||
this->moveCells(node, address, rowCount, colCount);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -106,14 +121,19 @@ private:
|
||||
int colCount;
|
||||
};
|
||||
|
||||
template<class P> class OffsetCellsExpressionVisitor : public ExpressionModifier<P> {
|
||||
template<class P>
|
||||
class OffsetCellsExpressionVisitor: public ExpressionModifier<P>
|
||||
{
|
||||
public:
|
||||
OffsetCellsExpressionVisitor(P &prop, int rowOffset, int colOffset)
|
||||
: ExpressionModifier<P>(prop),rowOffset(rowOffset),colOffset(colOffset)
|
||||
OffsetCellsExpressionVisitor(P& prop, int rowOffset, int colOffset)
|
||||
: ExpressionModifier<P>(prop)
|
||||
, rowOffset(rowOffset)
|
||||
, colOffset(colOffset)
|
||||
{}
|
||||
|
||||
void visit(Expression &node) override {
|
||||
this->offsetCells(node,rowOffset,colOffset);
|
||||
void visit(Expression& node) override
|
||||
{
|
||||
this->offsetCells(node, rowOffset, colOffset);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -121,6 +141,6 @@ private:
|
||||
int colOffset;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace App
|
||||
|
||||
#endif // RENAMEOBJECTIDENTIFIEREXPRESSIONVISITOR_H
|
||||
#endif // RENAMEOBJECTIDENTIFIEREXPRESSIONVISITOR_H
|
||||
|
||||
+118
-75
@@ -38,8 +38,8 @@
|
||||
#include "Range.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( disable : 4700 )
|
||||
#pragma warning( disable : 4723 )
|
||||
#pragma warning(disable : 4700)
|
||||
#pragma warning(disable : 4723)
|
||||
#endif
|
||||
|
||||
using namespace App;
|
||||
@@ -47,73 +47,106 @@ using namespace App;
|
||||
|
||||
PROPERTY_SOURCE(App::FeatureTest, App::DocumentObject)
|
||||
|
||||
const char* enums[]= {"Zero","One","Two","Three","Four",nullptr};
|
||||
const PropertyIntegerConstraint::Constraints intPercent = {0,100,1};
|
||||
const PropertyFloatConstraint::Constraints floatPercent = {0.0,100.0,1.0};
|
||||
const char* enums[] = {"Zero", "One", "Two", "Three", "Four", nullptr};
|
||||
const PropertyIntegerConstraint::Constraints intPercent = {0, 100, 1};
|
||||
const PropertyFloatConstraint::Constraints floatPercent = {0.0, 100.0, 1.0};
|
||||
|
||||
|
||||
FeatureTest::FeatureTest()
|
||||
{
|
||||
ADD_PROPERTY(Integer,(4711) );
|
||||
ADD_PROPERTY(Float ,(47.11f) );
|
||||
ADD_PROPERTY(Bool ,(true) );
|
||||
ADD_PROPERTY(BoolList,(false));
|
||||
ADD_PROPERTY(String ,("4711"));
|
||||
ADD_PROPERTY(Path ,("c:\\temp"));
|
||||
ADD_PROPERTY(StringList ,("4711"));
|
||||
// clang-format off
|
||||
ADD_PROPERTY(Integer, (4711));
|
||||
ADD_PROPERTY(Float, (47.11f));
|
||||
ADD_PROPERTY(Bool, (true));
|
||||
ADD_PROPERTY(BoolList, (false));
|
||||
ADD_PROPERTY(String, ("4711"));
|
||||
ADD_PROPERTY(Path, ("c:\\temp"));
|
||||
ADD_PROPERTY(StringList, ("4711"));
|
||||
|
||||
ADD_PROPERTY(Enum ,(4));
|
||||
Enum.setEnums(enums);
|
||||
ADD_PROPERTY(ConstraintInt ,(5));
|
||||
ConstraintInt.setConstraints(&intPercent);
|
||||
ADD_PROPERTY(ConstraintFloat ,(5.0));
|
||||
ConstraintFloat.setConstraints(&floatPercent);
|
||||
ADD_PROPERTY(Enum, (4));
|
||||
Enum.setEnums(enums);
|
||||
ADD_PROPERTY(ConstraintInt, (5));
|
||||
ConstraintInt.setConstraints(&intPercent);
|
||||
ADD_PROPERTY(ConstraintFloat, (5.0));
|
||||
ConstraintFloat.setConstraints(&floatPercent);
|
||||
|
||||
App::Color c;
|
||||
App::Material mat(App::Material::GOLD);
|
||||
ADD_PROPERTY(Colour ,(c) );
|
||||
ADD_PROPERTY(ColourList ,(c) );
|
||||
ADD_PROPERTY(Material ,(mat));
|
||||
ADD_PROPERTY(MaterialList,(mat));
|
||||
App::Color c;
|
||||
App::Material mat(App::Material::GOLD);
|
||||
ADD_PROPERTY(Colour, (c));
|
||||
ADD_PROPERTY(ColourList, (c));
|
||||
ADD_PROPERTY(Material, (mat));
|
||||
ADD_PROPERTY(MaterialList, (mat));
|
||||
|
||||
ADD_PROPERTY(Distance,(47.11f) );
|
||||
ADD_PROPERTY(Angle ,(3.0f) );
|
||||
ADD_PROPERTY(Distance, (47.11f));
|
||||
ADD_PROPERTY(Angle, (3.0f));
|
||||
|
||||
ADD_PROPERTY(IntegerList,(4711) );
|
||||
ADD_PROPERTY(FloatList ,(47.11f) );
|
||||
ADD_PROPERTY(IntegerList, (4711));
|
||||
ADD_PROPERTY(FloatList, (47.11f));
|
||||
|
||||
ADD_PROPERTY(Link ,(nullptr));
|
||||
ADD_PROPERTY(LinkSub ,(nullptr));
|
||||
ADD_PROPERTY(LinkList ,(nullptr));
|
||||
ADD_PROPERTY(LinkSubList,(nullptr));
|
||||
ADD_PROPERTY(Link, (nullptr));
|
||||
ADD_PROPERTY(LinkSub, (nullptr));
|
||||
ADD_PROPERTY(LinkList, (nullptr));
|
||||
ADD_PROPERTY(LinkSubList, (nullptr));
|
||||
|
||||
ADD_PROPERTY(Vector ,(1.0,2.0,3.0));
|
||||
ADD_PROPERTY(VectorList,(3.0,2.0,1.0));
|
||||
ADD_PROPERTY(Matrix ,(Base::Matrix4D(1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0)));
|
||||
ADD_PROPERTY(Placement ,(Base::Placement()));
|
||||
ADD_PROPERTY(Vector, (1.0, 2.0, 3.0));
|
||||
ADD_PROPERTY(VectorList, (3.0, 2.0, 1.0));
|
||||
ADD_PROPERTY(Matrix,
|
||||
(Base::Matrix4D( 1.0, 2.0, 3.0, 4.0,
|
||||
5.0, 6.0, 7.0, 8.0,
|
||||
9.0, 10.0, 11.0, 12.0,
|
||||
13.0, 14.0, 15.0, 16.0)));
|
||||
ADD_PROPERTY(Placement, (Base::Placement()));
|
||||
|
||||
// properties for recompute testing
|
||||
static const char* group = "Feature Test";
|
||||
ADD_PROPERTY_TYPE(Source1 ,(nullptr),group,Prop_None,"Source for testing links");
|
||||
ADD_PROPERTY_TYPE(Source2 ,(nullptr),group,Prop_None,"Source for testing links");
|
||||
ADD_PROPERTY_TYPE(SourceN ,(nullptr),group,Prop_None,"Source for testing links");
|
||||
ADD_PROPERTY_TYPE(ExecResult ,("empty"),group,Prop_None,"Result of the execution");
|
||||
ADD_PROPERTY_TYPE(ExceptionType ,(0),group,Prop_None,"The type of exception the execution method throws");
|
||||
ADD_PROPERTY_TYPE(ExecCount ,(0),group,Prop_None,"Number of executions");
|
||||
// properties for recompute testing
|
||||
static const char* group = "Feature Test";
|
||||
ADD_PROPERTY_TYPE(Source1, (nullptr), group, Prop_None, "Source for testing links");
|
||||
ADD_PROPERTY_TYPE(Source2, (nullptr), group, Prop_None, "Source for testing links");
|
||||
ADD_PROPERTY_TYPE(SourceN, (nullptr), group, Prop_None, "Source for testing links");
|
||||
ADD_PROPERTY_TYPE(ExecResult, ("empty"), group, Prop_None, "Result of the execution");
|
||||
ADD_PROPERTY_TYPE(ExceptionType,
|
||||
(0),
|
||||
group,
|
||||
Prop_None,
|
||||
"The type of exception the execution method throws");
|
||||
ADD_PROPERTY_TYPE(ExecCount, (0), group, Prop_None, "Number of executions");
|
||||
|
||||
// properties with types
|
||||
ADD_PROPERTY_TYPE(TypeHidden ,(4711),group,Prop_Hidden,"An example property which has the type 'Hidden'" );
|
||||
ADD_PROPERTY_TYPE(TypeReadOnly,(4711),group,Prop_ReadOnly ,"An example property which has the type 'ReadOnly'" );
|
||||
ADD_PROPERTY_TYPE(TypeOutput ,(4711),group,Prop_Output ,"An example property which has the type 'Output'" );
|
||||
ADD_PROPERTY_TYPE(TypeTransient,(4711),group,Prop_Transient ,"An example property which has the type 'Transient'" );
|
||||
ADD_PROPERTY_TYPE(TypeNoRecompute,(4711),group,Prop_NoRecompute,"An example property which has the type 'NoRecompute'");
|
||||
ADD_PROPERTY_TYPE(TypeAll ,(4711),group,(App::PropertyType) (Prop_Output|Prop_ReadOnly |Prop_Hidden ),
|
||||
"An example property which has the types 'Output', 'ReadOnly' and 'Hidden'");
|
||||
// properties with types
|
||||
ADD_PROPERTY_TYPE(TypeHidden,
|
||||
(4711),
|
||||
group,
|
||||
Prop_Hidden,
|
||||
"An example property which has the type 'Hidden'");
|
||||
ADD_PROPERTY_TYPE(TypeReadOnly,
|
||||
(4711),
|
||||
group,
|
||||
Prop_ReadOnly,
|
||||
"An example property which has the type 'ReadOnly'");
|
||||
ADD_PROPERTY_TYPE(TypeOutput,
|
||||
(4711),
|
||||
group,
|
||||
Prop_Output,
|
||||
"An example property which has the type 'Output'");
|
||||
ADD_PROPERTY_TYPE(TypeTransient,
|
||||
(4711),
|
||||
group,
|
||||
Prop_Transient,
|
||||
"An example property which has the type 'Transient'");
|
||||
ADD_PROPERTY_TYPE(TypeNoRecompute,
|
||||
(4711),
|
||||
group,
|
||||
Prop_NoRecompute,
|
||||
"An example property which has the type 'NoRecompute'");
|
||||
ADD_PROPERTY_TYPE(TypeAll,
|
||||
(4711),
|
||||
group,
|
||||
(App::PropertyType)(Prop_Output | Prop_ReadOnly | Prop_Hidden),
|
||||
"An example property which has the types 'Output', 'ReadOnly' and 'Hidden'");
|
||||
|
||||
ADD_PROPERTY(QuantityLength,(1.0));
|
||||
QuantityLength.setUnit(Base::Unit::Length);
|
||||
ADD_PROPERTY(QuantityOther,(5.0));
|
||||
QuantityOther.setUnit(Base::Unit(-3,1));
|
||||
ADD_PROPERTY(QuantityLength, (1.0));
|
||||
QuantityLength.setUnit(Base::Unit::Length);
|
||||
ADD_PROPERTY(QuantityOther, (5.0));
|
||||
QuantityOther.setUnit(Base::Unit(-3, 1));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
FeatureTest::~FeatureTest() = default;
|
||||
@@ -123,7 +156,7 @@ short FeatureTest::mustExecute() const
|
||||
return DocumentObject::mustExecute();
|
||||
}
|
||||
|
||||
DocumentObjectExecReturn *FeatureTest::execute()
|
||||
DocumentObjectExecReturn* FeatureTest::execute()
|
||||
{
|
||||
// Enum handling
|
||||
Enumeration enumObj1 = Enum.getEnum();
|
||||
@@ -159,19 +192,27 @@ DocumentObjectExecReturn *FeatureTest::execute()
|
||||
enumObj6.setEnums(list);
|
||||
enumObj6.setValue(list.back());
|
||||
|
||||
int *i=nullptr,j;
|
||||
int *i = nullptr, j;
|
||||
float f;
|
||||
void *s;
|
||||
void* s;
|
||||
std::string t;
|
||||
|
||||
// Code analyzers may complain about some errors. This can be ignored
|
||||
// because this is done on purpose to test the error handling mechanism
|
||||
switch(ExceptionType.getValue())
|
||||
{
|
||||
case 0: break;
|
||||
case 1: throw std::runtime_error("Test Exception");
|
||||
case 2: throw Base::RuntimeError("FeatureTestException::execute(): Testexception");
|
||||
default: (void)i; (void)j; (void)f; (void)s; (void)t; break;
|
||||
switch (ExceptionType.getValue()) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
throw std::runtime_error("Test Exception");
|
||||
case 2:
|
||||
throw Base::RuntimeError("FeatureTestException::execute(): Testexception");
|
||||
default:
|
||||
(void)i;
|
||||
(void)j;
|
||||
(void)f;
|
||||
(void)s;
|
||||
(void)t;
|
||||
break;
|
||||
}
|
||||
|
||||
ExecCount.setValue(ExecCount.getValue() + 1);
|
||||
@@ -188,12 +229,12 @@ PROPERTY_SOURCE(App::FeatureTestException, App::FeatureTest)
|
||||
|
||||
FeatureTestException::FeatureTestException()
|
||||
{
|
||||
ADD_PROPERTY(ExceptionType,(Base::Exception::getClassTypeId().getKey()) );
|
||||
ADD_PROPERTY(ExceptionType, (Base::Exception::getClassTypeId().getKey()));
|
||||
}
|
||||
|
||||
DocumentObjectExecReturn *FeatureTestException::execute()
|
||||
DocumentObjectExecReturn* FeatureTestException::execute()
|
||||
{
|
||||
//ExceptionType;
|
||||
// ExceptionType;
|
||||
throw Base::RuntimeError("FeatureTestException::execute(): Testexception ;-)");
|
||||
|
||||
return nullptr;
|
||||
@@ -211,7 +252,7 @@ FeatureTestColumn::FeatureTestColumn()
|
||||
ADD_PROPERTY_TYPE(Value, (0L), "Test", App::Prop_Output, "");
|
||||
}
|
||||
|
||||
DocumentObjectExecReturn *FeatureTestColumn::execute()
|
||||
DocumentObjectExecReturn* FeatureTestColumn::execute()
|
||||
{
|
||||
Value.setValue(decodeColumn(Column.getStrValue(), Silent.getValue()));
|
||||
return nullptr;
|
||||
@@ -229,7 +270,7 @@ FeatureTestRow::FeatureTestRow()
|
||||
ADD_PROPERTY_TYPE(Value, (0L), "Test", App::Prop_Output, "");
|
||||
}
|
||||
|
||||
DocumentObjectExecReturn *FeatureTestRow::execute()
|
||||
DocumentObjectExecReturn* FeatureTestRow::execute()
|
||||
{
|
||||
Value.setValue(decodeRow(Row.getStrValue(), Silent.getValue()));
|
||||
return nullptr;
|
||||
@@ -246,7 +287,7 @@ FeatureTestAbsAddress::FeatureTestAbsAddress()
|
||||
ADD_PROPERTY_TYPE(Valid, (false), "Test", PropertyType(Prop_Output | Prop_ReadOnly), "");
|
||||
}
|
||||
|
||||
DocumentObjectExecReturn *FeatureTestAbsAddress::execute()
|
||||
DocumentObjectExecReturn* FeatureTestAbsAddress::execute()
|
||||
{
|
||||
CellAddress address;
|
||||
Valid.setValue(address.parseAbsoluteAddress(Address.getValue()));
|
||||
@@ -266,7 +307,7 @@ FeatureTestPlacement::FeatureTestPlacement()
|
||||
ADD_PROPERTY_TYPE(MultRight, (Base::Placement()), "Test", Prop_Output, "");
|
||||
}
|
||||
|
||||
DocumentObjectExecReturn *FeatureTestPlacement::execute()
|
||||
DocumentObjectExecReturn* FeatureTestPlacement::execute()
|
||||
{
|
||||
Base::Placement p1 = Input1.getValue();
|
||||
Base::Placement q1 = Input1.getValue();
|
||||
@@ -295,8 +336,9 @@ FeatureTestAttribute::~FeatureTestAttribute()
|
||||
#if PYCXX_VERSION_MAJOR >= 7
|
||||
Py::ifPyErrorThrowCxxException();
|
||||
#else
|
||||
if (PyErr_Occurred())
|
||||
if (PyErr_Occurred()) {
|
||||
throw Py::RuntimeError();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (Py::RuntimeError& e) {
|
||||
@@ -308,7 +350,7 @@ FeatureTestAttribute::~FeatureTestAttribute()
|
||||
}
|
||||
}
|
||||
|
||||
DocumentObjectExecReturn *FeatureTestAttribute::execute()
|
||||
DocumentObjectExecReturn* FeatureTestAttribute::execute()
|
||||
{
|
||||
Base::PyGILStateLocker lock;
|
||||
try {
|
||||
@@ -316,8 +358,9 @@ DocumentObjectExecReturn *FeatureTestAttribute::execute()
|
||||
#if PYCXX_VERSION_MAJOR >= 7
|
||||
Py::ifPyErrorThrowCxxException();
|
||||
#else
|
||||
if (PyErr_Occurred())
|
||||
if (PyErr_Occurred()) {
|
||||
throw Py::AttributeError();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (Py::AttributeError& e) {
|
||||
|
||||
+94
-91
@@ -35,107 +35,110 @@ namespace App
|
||||
{
|
||||
|
||||
/// The testing feature
|
||||
class FeatureTest : public DocumentObject
|
||||
class FeatureTest: public DocumentObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(App::FeatureTest);
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(App::FeatureTest);
|
||||
|
||||
public:
|
||||
FeatureTest();
|
||||
FeatureTest();
|
||||
|
||||
~FeatureTest() override;
|
||||
~FeatureTest() override;
|
||||
|
||||
// Standard Properties (PropertyStandard.h)
|
||||
App::PropertyInteger Integer;
|
||||
App::PropertyFloat Float;
|
||||
App::PropertyBool Bool;
|
||||
App::PropertyBoolList BoolList;
|
||||
App::PropertyString String;
|
||||
App::PropertyPath Path;
|
||||
App::PropertyStringList StringList;
|
||||
// Standard Properties (PropertyStandard.h)
|
||||
App::PropertyInteger Integer;
|
||||
App::PropertyFloat Float;
|
||||
App::PropertyBool Bool;
|
||||
App::PropertyBoolList BoolList;
|
||||
App::PropertyString String;
|
||||
App::PropertyPath Path;
|
||||
App::PropertyStringList StringList;
|
||||
|
||||
App::PropertyColor Colour;
|
||||
App::PropertyColorList ColourList;
|
||||
App::PropertyMaterial Material;
|
||||
App::PropertyMaterialList MaterialList;
|
||||
App::PropertyColor Colour;
|
||||
App::PropertyColorList ColourList;
|
||||
App::PropertyMaterial Material;
|
||||
App::PropertyMaterialList MaterialList;
|
||||
|
||||
// special types
|
||||
App::PropertyDistance Distance;
|
||||
App::PropertyAngle Angle;
|
||||
// special types
|
||||
App::PropertyDistance Distance;
|
||||
App::PropertyAngle Angle;
|
||||
|
||||
// Constraint types
|
||||
App::PropertyEnumeration Enum;
|
||||
App::PropertyIntegerConstraint ConstraintInt;
|
||||
App::PropertyFloatConstraint ConstraintFloat;
|
||||
// Constraint types
|
||||
App::PropertyEnumeration Enum;
|
||||
App::PropertyIntegerConstraint ConstraintInt;
|
||||
App::PropertyFloatConstraint ConstraintFloat;
|
||||
|
||||
// Standard Properties (PrppertyStandard.h)
|
||||
App::PropertyIntegerList IntegerList;
|
||||
App::PropertyFloatList FloatList;
|
||||
// Standard Properties (PrppertyStandard.h)
|
||||
App::PropertyIntegerList IntegerList;
|
||||
App::PropertyFloatList FloatList;
|
||||
|
||||
// Standard Properties (PropertyLinks.h)
|
||||
App::PropertyLink Link;
|
||||
App::PropertyLinkSub LinkSub;
|
||||
App::PropertyLinkList LinkList;
|
||||
App::PropertyLinkSubList LinkSubList;
|
||||
// Standard Properties (PropertyLinks.h)
|
||||
App::PropertyLink Link;
|
||||
App::PropertyLinkSub LinkSub;
|
||||
App::PropertyLinkList LinkList;
|
||||
App::PropertyLinkSubList LinkSubList;
|
||||
|
||||
// Standard Properties (PropertyGeo.h)
|
||||
App::PropertyMatrix Matrix;
|
||||
App::PropertyVector Vector;
|
||||
App::PropertyVectorList VectorList;
|
||||
App::PropertyPlacement Placement;
|
||||
// Standard Properties (PropertyGeo.h)
|
||||
App::PropertyMatrix Matrix;
|
||||
App::PropertyVector Vector;
|
||||
App::PropertyVectorList VectorList;
|
||||
App::PropertyPlacement Placement;
|
||||
|
||||
// Properties to test the Document::recompute()
|
||||
App::PropertyLink Source1;
|
||||
App::PropertyLink Source2;
|
||||
App::PropertyLinkList SourceN;
|
||||
App::PropertyString ExecResult;
|
||||
App::PropertyInteger ExceptionType;
|
||||
App::PropertyInteger ExecCount;
|
||||
// Properties to test the Document::recompute()
|
||||
App::PropertyLink Source1;
|
||||
App::PropertyLink Source2;
|
||||
App::PropertyLinkList SourceN;
|
||||
App::PropertyString ExecResult;
|
||||
App::PropertyInteger ExceptionType;
|
||||
App::PropertyInteger ExecCount;
|
||||
|
||||
App::PropertyInteger TypeHidden;
|
||||
App::PropertyInteger TypeReadOnly;
|
||||
App::PropertyInteger TypeOutput;
|
||||
App::PropertyInteger TypeAll;
|
||||
App::PropertyInteger TypeTransient;
|
||||
App::PropertyInteger TypeNoRecompute;
|
||||
App::PropertyInteger TypeHidden;
|
||||
App::PropertyInteger TypeReadOnly;
|
||||
App::PropertyInteger TypeOutput;
|
||||
App::PropertyInteger TypeAll;
|
||||
App::PropertyInteger TypeTransient;
|
||||
App::PropertyInteger TypeNoRecompute;
|
||||
|
||||
App::PropertyQuantity QuantityLength;
|
||||
App::PropertyQuantity QuantityOther;
|
||||
//App::PropertyQuantity QuantityMass;
|
||||
//App::PropertyQuantity QuantityAngle;
|
||||
App::PropertyQuantity QuantityLength;
|
||||
App::PropertyQuantity QuantityOther;
|
||||
// App::PropertyQuantity QuantityMass;
|
||||
// App::PropertyQuantity QuantityAngle;
|
||||
|
||||
/** @name methods override Feature */
|
||||
//@{
|
||||
short mustExecute() const override;
|
||||
/// recalculate the Feature
|
||||
DocumentObjectExecReturn *execute() override;
|
||||
/// returns the type name of the ViewProvider
|
||||
//Hint: Probably it makes sense to have a view provider for unittests (e.g. Gui::ViewProviderTest)
|
||||
const char* getViewProviderName() const override {
|
||||
return "Gui::ViewProviderFeature";
|
||||
}
|
||||
//@}
|
||||
/** @name methods override Feature */
|
||||
//@{
|
||||
short mustExecute() const override;
|
||||
/// recalculate the Feature
|
||||
DocumentObjectExecReturn* execute() override;
|
||||
/// returns the type name of the ViewProvider
|
||||
// Hint: Probably it makes sense to have a view provider for unittests (e.g.
|
||||
// Gui::ViewProviderTest)
|
||||
const char* getViewProviderName() const override
|
||||
{
|
||||
return "Gui::ViewProviderFeature";
|
||||
}
|
||||
//@}
|
||||
};
|
||||
|
||||
/// The exception testing feature
|
||||
class FeatureTestException :public FeatureTest
|
||||
class FeatureTestException: public FeatureTest
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(App::FeatureTestException);
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(App::FeatureTestException);
|
||||
|
||||
public:
|
||||
FeatureTestException();
|
||||
FeatureTestException();
|
||||
|
||||
/// this property defines which kind of exceptio the feature throw on you
|
||||
App::PropertyInteger ExceptionType;
|
||||
/// this property defines which kind of exceptio the feature throw on you
|
||||
App::PropertyInteger ExceptionType;
|
||||
|
||||
/// recalculate the Feature and throw an exception
|
||||
DocumentObjectExecReturn *execute() override;
|
||||
/// returns the type name of the ViewProvider
|
||||
const char* getViewProviderName() const override {
|
||||
return "Gui::ViewProviderFeature";
|
||||
}
|
||||
/// recalculate the Feature and throw an exception
|
||||
DocumentObjectExecReturn* execute() override;
|
||||
/// returns the type name of the ViewProvider
|
||||
const char* getViewProviderName() const override
|
||||
{
|
||||
return "Gui::ViewProviderFeature";
|
||||
}
|
||||
};
|
||||
|
||||
class FeatureTestColumn : public DocumentObject
|
||||
class FeatureTestColumn: public DocumentObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(App::FeatureTestColumn);
|
||||
|
||||
@@ -143,17 +146,17 @@ public:
|
||||
FeatureTestColumn();
|
||||
|
||||
// Standard Properties (PropertyStandard.h)
|
||||
App::PropertyString Column;
|
||||
App::PropertyBool Silent;
|
||||
App::PropertyString Column;
|
||||
App::PropertyBool Silent;
|
||||
App::PropertyInteger Value;
|
||||
|
||||
/** @name methods override Feature */
|
||||
//@{
|
||||
DocumentObjectExecReturn *execute() override;
|
||||
DocumentObjectExecReturn* execute() override;
|
||||
//@}
|
||||
};
|
||||
|
||||
class FeatureTestRow : public DocumentObject
|
||||
class FeatureTestRow: public DocumentObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(App::FeatureTestRow);
|
||||
|
||||
@@ -161,29 +164,29 @@ public:
|
||||
FeatureTestRow();
|
||||
|
||||
// Standard Properties (PropertyStandard.h)
|
||||
App::PropertyString Row;
|
||||
App::PropertyBool Silent;
|
||||
App::PropertyString Row;
|
||||
App::PropertyBool Silent;
|
||||
App::PropertyInteger Value;
|
||||
|
||||
/** @name methods override Feature */
|
||||
//@{
|
||||
DocumentObjectExecReturn *execute() override;
|
||||
DocumentObjectExecReturn* execute() override;
|
||||
//@}
|
||||
};
|
||||
|
||||
class FeatureTestAbsAddress : public DocumentObject
|
||||
class FeatureTestAbsAddress: public DocumentObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(App::FeatureTestAbsAddress);
|
||||
|
||||
public:
|
||||
FeatureTestAbsAddress();
|
||||
DocumentObjectExecReturn *execute() override;
|
||||
DocumentObjectExecReturn* execute() override;
|
||||
|
||||
App::PropertyString Address;
|
||||
App::PropertyBool Valid;
|
||||
};
|
||||
|
||||
class FeatureTestPlacement : public DocumentObject
|
||||
class FeatureTestPlacement: public DocumentObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(App::FeatureTestPlacement);
|
||||
|
||||
@@ -198,24 +201,24 @@ public:
|
||||
|
||||
/** @name methods override Feature */
|
||||
//@{
|
||||
DocumentObjectExecReturn *execute() override;
|
||||
DocumentObjectExecReturn* execute() override;
|
||||
//@}
|
||||
};
|
||||
|
||||
class FeatureTestAttribute : public DocumentObject
|
||||
class FeatureTestAttribute: public DocumentObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(App::FeatureTestAttribute);
|
||||
|
||||
public:
|
||||
FeatureTestAttribute();
|
||||
~FeatureTestAttribute() override;
|
||||
DocumentObjectExecReturn *execute() override;
|
||||
DocumentObjectExecReturn* execute() override;
|
||||
|
||||
App::PropertyPythonObject Object;
|
||||
App::PropertyString Attribute;
|
||||
};
|
||||
|
||||
|
||||
} //namespace App
|
||||
} // namespace App
|
||||
|
||||
#endif // APP_FEATURETEST_H
|
||||
#endif // APP_FEATURETEST_H
|
||||
|
||||
+62
-43
@@ -47,12 +47,12 @@ PROPERTY_SOURCE(App::GeoFeature, App::DocumentObject)
|
||||
|
||||
GeoFeature::GeoFeature()
|
||||
{
|
||||
ADD_PROPERTY_TYPE(Placement,(Base::Placement()),nullptr,Prop_NoRecompute,nullptr);
|
||||
ADD_PROPERTY_TYPE(Placement, (Base::Placement()), nullptr, Prop_NoRecompute, nullptr);
|
||||
}
|
||||
|
||||
GeoFeature::~GeoFeature() = default;
|
||||
|
||||
void GeoFeature::transformPlacement(const Base::Placement &transform)
|
||||
void GeoFeature::transformPlacement(const Base::Placement& transform)
|
||||
{
|
||||
Base::Placement plm = this->Placement.getValue();
|
||||
plm = transform * plm;
|
||||
@@ -66,7 +66,7 @@ Base::Placement GeoFeature::globalPlacement() const
|
||||
auto ext = group->getExtensionByType<GeoFeatureGroupExtension>();
|
||||
return ext->globalGroupPlacement() * Placement.getValue();
|
||||
}
|
||||
return Placement.getValue();
|
||||
return Placement.getValue();
|
||||
}
|
||||
|
||||
const PropertyComplexGeoData* GeoFeature::getPropertyOfGeometry() const
|
||||
@@ -78,22 +78,22 @@ PyObject* GeoFeature::getPyObject()
|
||||
{
|
||||
if (PythonObject.is(Py::_None())) {
|
||||
// ref counter is set to 1
|
||||
PythonObject = Py::Object(new GeoFeaturePy(this),true);
|
||||
PythonObject = Py::Object(new GeoFeaturePy(this), true);
|
||||
}
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
|
||||
ElementNamePair
|
||||
GeoFeature::getElementName(const char *name, ElementNameType type) const
|
||||
ElementNamePair GeoFeature::getElementName(const char* name, ElementNameType type) const
|
||||
{
|
||||
(void)type;
|
||||
|
||||
if(!name)
|
||||
if (!name) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto prop = getPropertyOfGeometry();
|
||||
if (!prop) {
|
||||
return ElementNamePair("",name);
|
||||
return ElementNamePair("", name);
|
||||
}
|
||||
|
||||
auto geo = prop->getComplexData();
|
||||
@@ -104,8 +104,8 @@ GeoFeature::getElementName(const char *name, ElementNameType type) const
|
||||
return _getElementName(name, geo->getElementName(name));
|
||||
}
|
||||
|
||||
ElementNamePair
|
||||
GeoFeature::_getElementName(const char* name, const Data::MappedElement& mapped) const
|
||||
ElementNamePair GeoFeature::_getElementName(const char* name,
|
||||
const Data::MappedElement& mapped) const
|
||||
{
|
||||
ElementNamePair ret;
|
||||
if (mapped.index && mapped.name) {
|
||||
@@ -123,9 +123,9 @@ GeoFeature::_getElementName(const char* name, const Data::MappedElement& mapped)
|
||||
// missing reference
|
||||
std::ostringstream ss;
|
||||
ss << Data::MISSING_PREFIX << dot + 1;
|
||||
return ElementNamePair(name, ss.str().c_str() );
|
||||
return ElementNamePair(name, ss.str().c_str());
|
||||
}
|
||||
return ElementNamePair(name,"");
|
||||
return ElementNamePair(name, "");
|
||||
}
|
||||
else {
|
||||
std::string oldName;
|
||||
@@ -134,53 +134,70 @@ GeoFeature::_getElementName(const char* name, const Data::MappedElement& mapped)
|
||||
}
|
||||
}
|
||||
|
||||
DocumentObject *GeoFeature::resolveElement(DocumentObject *obj, const char *subname,
|
||||
ElementNamePair &elementName, bool append,
|
||||
ElementNameType type, const DocumentObject *filter,
|
||||
const char **_element, GeoFeature **geoFeature)
|
||||
DocumentObject* GeoFeature::resolveElement(DocumentObject* obj,
|
||||
const char* subname,
|
||||
ElementNamePair& elementName,
|
||||
bool append,
|
||||
ElementNameType type,
|
||||
const DocumentObject* filter,
|
||||
const char** _element,
|
||||
GeoFeature** geoFeature)
|
||||
{
|
||||
elementName.newName.clear();
|
||||
elementName.oldName.clear();
|
||||
if(!obj || !obj->isAttachedToDocument())
|
||||
if (!obj || !obj->isAttachedToDocument()) {
|
||||
return nullptr;
|
||||
if(!subname)
|
||||
}
|
||||
if (!subname) {
|
||||
subname = "";
|
||||
const char *element = Data::findElementName(subname);
|
||||
if(_element) *_element = element;
|
||||
}
|
||||
const char* element = Data::findElementName(subname);
|
||||
if (_element) {
|
||||
*_element = element;
|
||||
}
|
||||
auto sobj = obj->getSubObject(std::string(subname, element).c_str());
|
||||
if(!sobj)
|
||||
if (!sobj) {
|
||||
return nullptr;
|
||||
}
|
||||
auto linked = sobj->getLinkedObject(true);
|
||||
auto geo = Base::freecad_dynamic_cast<GeoFeature>(linked);
|
||||
if(!geo && linked) {
|
||||
if (!geo && linked) {
|
||||
auto ext = linked->getExtensionByType<LinkBaseExtension>(true);
|
||||
if(ext)
|
||||
if (ext) {
|
||||
geo = Base::freecad_dynamic_cast<GeoFeature>(ext->getTrueLinkedObject(true));
|
||||
}
|
||||
}
|
||||
if(geoFeature)
|
||||
if (geoFeature) {
|
||||
*geoFeature = geo;
|
||||
if(filter && geo!=filter)
|
||||
}
|
||||
if (filter && geo != filter) {
|
||||
return nullptr;
|
||||
if(!element || !element[0]) {
|
||||
if(append)
|
||||
}
|
||||
if (!element || !element[0]) {
|
||||
if (append) {
|
||||
elementName.oldName = Data::oldElementName(subname);
|
||||
}
|
||||
return sobj;
|
||||
}
|
||||
|
||||
if(!geo || hasHiddenMarker(element)) {
|
||||
if(!append)
|
||||
if (!geo || hasHiddenMarker(element)) {
|
||||
if (!append) {
|
||||
elementName.oldName = element;
|
||||
else
|
||||
}
|
||||
else {
|
||||
elementName.oldName = Data::oldElementName(subname);
|
||||
}
|
||||
return sobj;
|
||||
}
|
||||
if(!append)
|
||||
elementName = geo->getElementName(element,type);
|
||||
else{
|
||||
const auto &names = geo->getElementName(element,type);
|
||||
std::string prefix(subname,element-subname);
|
||||
if(!names.newName.empty())
|
||||
if (!append) {
|
||||
elementName = geo->getElementName(element, type);
|
||||
}
|
||||
else {
|
||||
const auto& names = geo->getElementName(element, type);
|
||||
std::string prefix(subname, element - subname);
|
||||
if (!names.newName.empty()) {
|
||||
elementName.newName = prefix + names.newName;
|
||||
}
|
||||
elementName.oldName = prefix + names.oldName;
|
||||
}
|
||||
return sobj;
|
||||
@@ -264,12 +281,12 @@ std::vector<const char*> GeoFeature::getElementTypes(bool /*all*/) const
|
||||
return prop->getComplexData()->getElementTypes();
|
||||
}
|
||||
|
||||
std::vector<Data::IndexedName>
|
||||
GeoFeature::getHigherElements(const char *element, bool silent) const
|
||||
std::vector<Data::IndexedName> GeoFeature::getHigherElements(const char* element, bool silent) const
|
||||
{
|
||||
auto prop = getPropertyOfGeometry();
|
||||
if (!prop)
|
||||
if (!prop) {
|
||||
return {};
|
||||
}
|
||||
return prop->getComplexData()->getHigherElements(element, silent);
|
||||
}
|
||||
|
||||
@@ -284,8 +301,8 @@ Base::Placement GeoFeature::getPlacementFromProp(App::DocumentObject* obj, const
|
||||
}
|
||||
|
||||
Base::Placement GeoFeature::getGlobalPlacement(App::DocumentObject* targetObj,
|
||||
App::DocumentObject* rootObj,
|
||||
const std::string& sub)
|
||||
App::DocumentObject* rootObj,
|
||||
const std::string& sub)
|
||||
{
|
||||
if (!targetObj || !rootObj || sub.empty()) {
|
||||
return Base::Placement();
|
||||
@@ -295,7 +312,9 @@ Base::Placement GeoFeature::getGlobalPlacement(App::DocumentObject* targetObj,
|
||||
App::Document* doc = rootObj->getDocument();
|
||||
Base::Placement plc = getPlacementFromProp(rootObj, "Placement");
|
||||
|
||||
if (targetObj == rootObj) return plc;
|
||||
if (targetObj == rootObj) {
|
||||
return plc;
|
||||
}
|
||||
|
||||
for (auto& name : names) {
|
||||
App::DocumentObject* obj = doc->getObject(name.c_str());
|
||||
@@ -319,7 +338,7 @@ Base::Placement GeoFeature::getGlobalPlacement(App::DocumentObject* targetObj,
|
||||
}
|
||||
|
||||
Base::Placement GeoFeature::getGlobalPlacement(App::DocumentObject* targetObj,
|
||||
App::PropertyXLinkSub* prop)
|
||||
App::PropertyXLinkSub* prop)
|
||||
{
|
||||
if (!targetObj || !prop) {
|
||||
return Base::Placement();
|
||||
|
||||
+45
-33
@@ -36,7 +36,7 @@ namespace App
|
||||
|
||||
/** Base class of all geometric document objects.
|
||||
*/
|
||||
class AppExport GeoFeature : public App::DocumentObject
|
||||
class AppExport GeoFeature: public App::DocumentObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(App::GeoFeature);
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
* was only called by alignment task (Edit->Alignment)
|
||||
* @param transform (input).
|
||||
*/
|
||||
virtual void transformPlacement(const Base::Placement &transform);
|
||||
virtual void transformPlacement(const Base::Placement& transform);
|
||||
/**
|
||||
* This method returns the main property of a geometric object that holds
|
||||
* the actual geometry. For a part object this is the Shape property, for
|
||||
@@ -68,14 +68,15 @@ public:
|
||||
*/
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
/// Specify the type of element name to return when calling getElementName()
|
||||
enum ElementNameType {
|
||||
/// Specify the type of element name to return when calling getElementName()
|
||||
enum ElementNameType
|
||||
{
|
||||
/// Normal usage
|
||||
Normal=0,
|
||||
Normal = 0,
|
||||
/// For importing
|
||||
Import=1,
|
||||
Import = 1,
|
||||
/// For exporting
|
||||
Export=2,
|
||||
Export = 2,
|
||||
};
|
||||
|
||||
/** Return the new and old style sub-element name
|
||||
@@ -86,12 +87,13 @@ public:
|
||||
* @return a struct with the newName and oldName. New element name may be empty.
|
||||
*/
|
||||
virtual ElementNamePair getElementName( // NOLINT(google-default-arguments)
|
||||
const char *name, ElementNameType type=Normal) const;
|
||||
const char* name,
|
||||
ElementNameType type = Normal) const;
|
||||
|
||||
/** Resolve both the new and old style element name
|
||||
*
|
||||
* @param obj: top parent object
|
||||
* @param subname: subname reference
|
||||
* @param subname: subname reference
|
||||
* @param elementName: output of a pair(newElementName,oldElementName)
|
||||
* @param append: Whether to include subname prefix into the returned
|
||||
* element name
|
||||
@@ -102,22 +104,26 @@ public:
|
||||
*
|
||||
* @return Return the owner object of the element
|
||||
*/
|
||||
static DocumentObject *resolveElement(App::DocumentObject *obj,
|
||||
const char *subname, ElementNamePair &elementName,
|
||||
bool append=false, ElementNameType type=Normal,
|
||||
const DocumentObject *filter=nullptr,const char **element=nullptr, GeoFeature **geo=nullptr);
|
||||
static DocumentObject* resolveElement(App::DocumentObject* obj,
|
||||
const char* subname,
|
||||
ElementNamePair& elementName,
|
||||
bool append = false,
|
||||
ElementNameType type = Normal,
|
||||
const DocumentObject* filter = nullptr,
|
||||
const char** element = nullptr,
|
||||
GeoFeature** geo = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Deprecated. Calculates the placement in the global reference coordinate system
|
||||
*
|
||||
*
|
||||
* Deprecated: This does not handle App::Links correctly. Use getGlobalPlacement() instead.
|
||||
* In FreeCAD the GeoFeature placement describes the local placement of the object in its parent
|
||||
* coordinate system. This is however not always the same as the global reference system. If the
|
||||
* object is in a GeoFeatureGroup, hence in another local coordinate system, the Placement
|
||||
* property does only give the local transformation. This function can be used to calculate the
|
||||
* placement of the object in the global reference coordinate system taking all stacked local
|
||||
* property does only give the local transformation. This function can be used to calculate the
|
||||
* placement of the object in the global reference coordinate system taking all stacked local
|
||||
* systems into account.
|
||||
*
|
||||
*
|
||||
* @return Base::Placement The transformation from the global reference coordinate system
|
||||
*/
|
||||
Base::Placement globalPlacement() const;
|
||||
@@ -148,7 +154,8 @@ public:
|
||||
*
|
||||
* @return bool whether or not a direction is found.
|
||||
*/
|
||||
virtual bool getCameraAlignmentDirection(Base::Vector3d& direction, const char* subname = nullptr) const;
|
||||
virtual bool getCameraAlignmentDirection(Base::Vector3d& direction,
|
||||
const char* subname = nullptr) const;
|
||||
/** Search sub element using internal cached geometry
|
||||
*
|
||||
* @param element: element name
|
||||
@@ -164,36 +171,41 @@ public:
|
||||
* code may call this function to search for the new element name that
|
||||
* reference to the same geometry of the old element.
|
||||
*/
|
||||
virtual const std::vector<std::string>& searchElementCache(const std::string &element,
|
||||
Data::SearchOptions options = Data::SearchOption::CheckGeometry,
|
||||
double tol = 1e-7,
|
||||
double atol = 1e-10) const;
|
||||
virtual const std::vector<std::string>&
|
||||
searchElementCache(const std::string& element,
|
||||
Data::SearchOptions options = Data::SearchOption::CheckGeometry,
|
||||
double tol = 1e-7,
|
||||
double atol = 1e-10) const;
|
||||
|
||||
static bool hasMissingElement(const char *subname);
|
||||
static bool hasMissingElement(const char* subname);
|
||||
|
||||
/// Return the object that owns the shape that contains the give element name
|
||||
virtual DocumentObject *getElementOwner(const Data::MappedName & /*name*/) const
|
||||
{return nullptr;}
|
||||
virtual DocumentObject* getElementOwner(const Data::MappedName& /*name*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual std::vector<const char *> getElementTypes(bool all=true) const;
|
||||
virtual std::vector<const char*> getElementTypes(bool all = true) const;
|
||||
|
||||
/// Return the higher level element names of the given element
|
||||
virtual std::vector<Data::IndexedName> getHigherElements(const char *name, bool silent=false) const;
|
||||
virtual std::vector<Data::IndexedName> getHigherElements(const char* name,
|
||||
bool silent = false) const;
|
||||
|
||||
static Base::Placement getPlacementFromProp(DocumentObject* obj, const char* propName);
|
||||
static Base::Placement getGlobalPlacement(DocumentObject* targetObj, DocumentObject* rootObj, const std::string& sub);
|
||||
static Base::Placement
|
||||
getGlobalPlacement(DocumentObject* targetObj, DocumentObject* rootObj, const std::string& sub);
|
||||
static Base::Placement getGlobalPlacement(DocumentObject* targetObj, PropertyXLinkSub* prop);
|
||||
|
||||
protected:
|
||||
void onChanged(const Property* prop) override;
|
||||
// void onDocumentRestored() override;
|
||||
// void onDocumentRestored() override;
|
||||
void updateElementReference();
|
||||
|
||||
protected:
|
||||
ElementNamePair _getElementName(const char* name,
|
||||
const Data::MappedElement& mapped) const;
|
||||
ElementNamePair _getElementName(const char* name, const Data::MappedElement& mapped) const;
|
||||
};
|
||||
|
||||
} //namespace App
|
||||
} // namespace App
|
||||
|
||||
|
||||
#endif // APP_GEOFEATURE_H
|
||||
#endif // APP_GEOFEATURE_H
|
||||
|
||||
+1256
-893
File diff suppressed because it is too large
Load Diff
+401
-285
@@ -33,22 +33,23 @@
|
||||
#include "PropertyLinks.h"
|
||||
|
||||
|
||||
//FIXME: ISO C++11 requires at least one argument for the "..." in a variadic macro
|
||||
// FIXME: ISO C++11 requires at least one argument for the "..." in a variadic macro
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
#endif
|
||||
|
||||
#define LINK_THROW(_type,_msg) do{\
|
||||
if(FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))\
|
||||
FC_ERR(_msg);\
|
||||
throw _type(_msg);\
|
||||
}while(0)
|
||||
#define LINK_THROW(_type, _msg) \
|
||||
do { \
|
||||
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) \
|
||||
FC_ERR(_msg); \
|
||||
throw _type(_msg); \
|
||||
} while (0)
|
||||
|
||||
namespace App
|
||||
{
|
||||
|
||||
class AppExport LinkBaseExtension : public App::DocumentObjectExtension
|
||||
class AppExport LinkBaseExtension: public App::DocumentObjectExtension
|
||||
{
|
||||
EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(App::LinkExtension);
|
||||
using inherited = App::DocumentObjectExtension;
|
||||
@@ -59,9 +60,10 @@ public:
|
||||
|
||||
PropertyBool _LinkTouched;
|
||||
PropertyInteger _LinkOwner;
|
||||
PropertyLinkList _ChildCache; // cache for plain group expansion
|
||||
PropertyLinkList _ChildCache; // cache for plain group expansion
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
LinkModeNone,
|
||||
LinkModeAutoDelete,
|
||||
LinkModeAutoLink,
|
||||
@@ -76,267 +78,365 @@ public:
|
||||
*/
|
||||
//@{
|
||||
|
||||
#define LINK_PARAM_LINK_PLACEMENT(...) \
|
||||
(LinkPlacement, Base::Placement, App::PropertyPlacement, Base::Placement(), "Link placement", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_LINK_PLACEMENT(...) \
|
||||
(LinkPlacement, \
|
||||
Base::Placement, \
|
||||
App::PropertyPlacement, \
|
||||
Base::Placement(), \
|
||||
"Link placement", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_PLACEMENT(...) \
|
||||
(Placement, Base::Placement, App::PropertyPlacement, Base::Placement(), \
|
||||
"Alias to LinkPlacement to make the link object compatibale with other objects", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_PLACEMENT(...) \
|
||||
(Placement, \
|
||||
Base::Placement, \
|
||||
App::PropertyPlacement, \
|
||||
Base::Placement(), \
|
||||
"Alias to LinkPlacement to make the link object compatibale with other objects", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_OBJECT(...) \
|
||||
#define LINK_PARAM_OBJECT(...) \
|
||||
(LinkedObject, App::DocumentObject*, App::PropertyLink, 0, "Linked object", ##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_TRANSFORM(...) \
|
||||
(LinkTransform, bool, App::PropertyBool, false, \
|
||||
"Set to false to override linked object's placement", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_TRANSFORM(...) \
|
||||
(LinkTransform, \
|
||||
bool, \
|
||||
App::PropertyBool, \
|
||||
false, \
|
||||
"Set to false to override linked object's placement", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_CLAIM_CHILD(...) \
|
||||
(LinkClaimChild, bool, App::PropertyBool, false, \
|
||||
"Claim the linked object as a child", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_CLAIM_CHILD(...) \
|
||||
(LinkClaimChild, \
|
||||
bool, \
|
||||
App::PropertyBool, \
|
||||
false, \
|
||||
"Claim the linked object as a child", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_COPY_ON_CHANGE(...) \
|
||||
(LinkCopyOnChange, long, App::PropertyEnumeration, ((long)0), \
|
||||
"Disabled: disable copy on change\n"\
|
||||
"Enabled: enable copy linked object on change of any of its properties marked as CopyOnChange\n"\
|
||||
"Owned: indicate the linked object has been copied and is own owned by the link. And the\n"\
|
||||
" the link will try to sync any change of the original linked object back to the copy.",\
|
||||
##__VA_ARGS__)
|
||||
#define LINK_PARAM_COPY_ON_CHANGE(...) \
|
||||
(LinkCopyOnChange, \
|
||||
long, \
|
||||
App::PropertyEnumeration, \
|
||||
((long)0), \
|
||||
"Disabled: disable copy on change\n" \
|
||||
"Enabled: enable copy linked object on change of any of its properties marked as " \
|
||||
"CopyOnChange\n" \
|
||||
"Owned: indicate the linked object has been copied and is own owned by the link. And the\n" \
|
||||
" the link will try to sync any change of the original linked object back to the " \
|
||||
"copy.", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_COPY_ON_CHANGE_SOURCE(...) \
|
||||
(LinkCopyOnChangeSource, App::DocumentObject*, App::PropertyLink, 0, "The copy on change source object", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_COPY_ON_CHANGE_SOURCE(...) \
|
||||
(LinkCopyOnChangeSource, \
|
||||
App::DocumentObject*, \
|
||||
App::PropertyLink, \
|
||||
0, \
|
||||
"The copy on change source object", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_COPY_ON_CHANGE_GROUP(...) \
|
||||
(LinkCopyOnChangeGroup, App::DocumentObject*, App::PropertyLink, 0, \
|
||||
"Linked to a internal group object for holding on change copies", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_COPY_ON_CHANGE_GROUP(...) \
|
||||
(LinkCopyOnChangeGroup, \
|
||||
App::DocumentObject*, \
|
||||
App::PropertyLink, \
|
||||
0, \
|
||||
"Linked to a internal group object for holding on change copies", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_COPY_ON_CHANGE_TOUCHED(...) \
|
||||
(LinkCopyOnChangeTouched, bool, App::PropertyBool, 0, "Indicating the copy on change source object has been changed", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_COPY_ON_CHANGE_TOUCHED(...) \
|
||||
(LinkCopyOnChangeTouched, \
|
||||
bool, \
|
||||
App::PropertyBool, \
|
||||
0, \
|
||||
"Indicating the copy on change source object has been changed", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_SCALE(...) \
|
||||
#define LINK_PARAM_SCALE(...) \
|
||||
(Scale, double, App::PropertyFloat, 1.0, "Scale factor", ##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_SCALE_VECTOR(...) \
|
||||
(ScaleVector, Base::Vector3d, App::PropertyVector, Base::Vector3d(1,1,1), "Scale factors", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_SCALE_VECTOR(...) \
|
||||
(ScaleVector, \
|
||||
Base::Vector3d, \
|
||||
App::PropertyVector, \
|
||||
Base::Vector3d(1, 1, 1), \
|
||||
"Scale factors", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_PLACEMENTS(...) \
|
||||
(PlacementList, std::vector<Base::Placement>, App::PropertyPlacementList, std::vector<Base::Placement>(),\
|
||||
"The placement for each link element", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_PLACEMENTS(...) \
|
||||
(PlacementList, \
|
||||
std::vector<Base::Placement>, \
|
||||
App::PropertyPlacementList, \
|
||||
std::vector<Base::Placement>(), \
|
||||
"The placement for each link element", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_SCALES(...) \
|
||||
(ScaleList, std::vector<Base::Vector3d>, App::PropertyVectorList, std::vector<Base::Vector3d>(),\
|
||||
"The scale factors for each link element", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_SCALES(...) \
|
||||
(ScaleList, \
|
||||
std::vector<Base::Vector3d>, \
|
||||
App::PropertyVectorList, \
|
||||
std::vector<Base::Vector3d>(), \
|
||||
"The scale factors for each link element", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_VISIBILITIES(...) \
|
||||
(VisibilityList, boost::dynamic_bitset<>, App::PropertyBoolList, boost::dynamic_bitset<>(),\
|
||||
"The visibility state of each link element", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_VISIBILITIES(...) \
|
||||
(VisibilityList, \
|
||||
boost::dynamic_bitset<>, \
|
||||
App::PropertyBoolList, \
|
||||
boost::dynamic_bitset<>(), \
|
||||
"The visibility state of each link element", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_COUNT(...) \
|
||||
#define LINK_PARAM_COUNT(...) \
|
||||
(ElementCount, int, App::PropertyInteger, 0, "Link element count", ##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_ELEMENTS(...) \
|
||||
(ElementList, std::vector<App::DocumentObject*>, App::PropertyLinkList, std::vector<App::DocumentObject*>(),\
|
||||
"The link element object list", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_ELEMENTS(...) \
|
||||
(ElementList, \
|
||||
std::vector<App::DocumentObject*>, \
|
||||
App::PropertyLinkList, \
|
||||
std::vector<App::DocumentObject*>(), \
|
||||
"The link element object list", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_SHOW_ELEMENT(...) \
|
||||
#define LINK_PARAM_SHOW_ELEMENT(...) \
|
||||
(ShowElement, bool, App::PropertyBool, true, "Enable link element list", ##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_MODE(...) \
|
||||
#define LINK_PARAM_MODE(...) \
|
||||
(LinkMode, long, App::PropertyEnumeration, ((long)0), "Link group mode", ##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_LINK_EXECUTE(...) \
|
||||
(LinkExecute, const char*, App::PropertyString, (""),\
|
||||
"Link execute function. Default to 'appLinkExecute'. 'None' to disable.", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_LINK_EXECUTE(...) \
|
||||
(LinkExecute, \
|
||||
const char*, \
|
||||
App::PropertyString, \
|
||||
(""), \
|
||||
"Link execute function. Default to 'appLinkExecute'. 'None' to disable.", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_COLORED_ELEMENTS(...) \
|
||||
(ColoredElements, App::DocumentObject*, App::PropertyLinkSubHidden, \
|
||||
0, "Link colored elements", ##__VA_ARGS__)
|
||||
#define LINK_PARAM_COLORED_ELEMENTS(...) \
|
||||
(ColoredElements, \
|
||||
App::DocumentObject*, \
|
||||
App::PropertyLinkSubHidden, \
|
||||
0, \
|
||||
"Link colored elements", \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM(_param) (LINK_PARAM_##_param())
|
||||
|
||||
#define LINK_PNAME(_param) BOOST_PP_TUPLE_ELEM(0,_param)
|
||||
#define LINK_PTYPE(_param) BOOST_PP_TUPLE_ELEM(1,_param)
|
||||
#define LINK_PPTYPE(_param) BOOST_PP_TUPLE_ELEM(2,_param)
|
||||
#define LINK_PDEF(_param) BOOST_PP_TUPLE_ELEM(3,_param)
|
||||
#define LINK_PDOC(_param) BOOST_PP_TUPLE_ELEM(4,_param)
|
||||
#define LINK_PNAME(_param) BOOST_PP_TUPLE_ELEM(0, _param)
|
||||
#define LINK_PTYPE(_param) BOOST_PP_TUPLE_ELEM(1, _param)
|
||||
#define LINK_PPTYPE(_param) BOOST_PP_TUPLE_ELEM(2, _param)
|
||||
#define LINK_PDEF(_param) BOOST_PP_TUPLE_ELEM(3, _param)
|
||||
#define LINK_PDOC(_param) BOOST_PP_TUPLE_ELEM(4, _param)
|
||||
|
||||
#define LINK_PINDEX(_param) BOOST_PP_CAT(Prop,LINK_PNAME(_param))
|
||||
#define LINK_PINDEX(_param) BOOST_PP_CAT(Prop, LINK_PNAME(_param))
|
||||
//@}
|
||||
|
||||
#define LINK_PARAMS \
|
||||
LINK_PARAM(PLACEMENT)\
|
||||
LINK_PARAM(LINK_PLACEMENT)\
|
||||
LINK_PARAM(OBJECT)\
|
||||
LINK_PARAM(CLAIM_CHILD)\
|
||||
LINK_PARAM(TRANSFORM)\
|
||||
LINK_PARAM(SCALE)\
|
||||
LINK_PARAM(SCALE_VECTOR)\
|
||||
LINK_PARAM(PLACEMENTS)\
|
||||
LINK_PARAM(SCALES)\
|
||||
LINK_PARAM(VISIBILITIES)\
|
||||
LINK_PARAM(COUNT)\
|
||||
LINK_PARAM(ELEMENTS)\
|
||||
LINK_PARAM(SHOW_ELEMENT)\
|
||||
LINK_PARAM(MODE)\
|
||||
LINK_PARAM(LINK_EXECUTE)\
|
||||
LINK_PARAM(COLORED_ELEMENTS)\
|
||||
LINK_PARAM(COPY_ON_CHANGE)\
|
||||
LINK_PARAM(COPY_ON_CHANGE_SOURCE)\
|
||||
LINK_PARAM(COPY_ON_CHANGE_GROUP)\
|
||||
LINK_PARAM(COPY_ON_CHANGE_TOUCHED)\
|
||||
#define LINK_PARAMS \
|
||||
LINK_PARAM(PLACEMENT) \
|
||||
LINK_PARAM(LINK_PLACEMENT) \
|
||||
LINK_PARAM(OBJECT) \
|
||||
LINK_PARAM(CLAIM_CHILD) \
|
||||
LINK_PARAM(TRANSFORM) \
|
||||
LINK_PARAM(SCALE) \
|
||||
LINK_PARAM(SCALE_VECTOR) \
|
||||
LINK_PARAM(PLACEMENTS) \
|
||||
LINK_PARAM(SCALES) \
|
||||
LINK_PARAM(VISIBILITIES) \
|
||||
LINK_PARAM(COUNT) \
|
||||
LINK_PARAM(ELEMENTS) \
|
||||
LINK_PARAM(SHOW_ELEMENT) \
|
||||
LINK_PARAM(MODE) \
|
||||
LINK_PARAM(LINK_EXECUTE) \
|
||||
LINK_PARAM(COLORED_ELEMENTS) \
|
||||
LINK_PARAM(COPY_ON_CHANGE) \
|
||||
LINK_PARAM(COPY_ON_CHANGE_SOURCE) \
|
||||
LINK_PARAM(COPY_ON_CHANGE_GROUP) \
|
||||
LINK_PARAM(COPY_ON_CHANGE_TOUCHED)
|
||||
|
||||
enum PropIndex {
|
||||
#define LINK_PINDEX_DEFINE(_1,_2,_param) LINK_PINDEX(_param),
|
||||
enum PropIndex
|
||||
{
|
||||
#define LINK_PINDEX_DEFINE(_1, _2, _param) LINK_PINDEX(_param),
|
||||
|
||||
// defines Prop##Name enumeration value
|
||||
BOOST_PP_SEQ_FOR_EACH(LINK_PINDEX_DEFINE,_,LINK_PARAMS)
|
||||
PropMax
|
||||
BOOST_PP_SEQ_FOR_EACH(LINK_PINDEX_DEFINE, _, LINK_PARAMS) PropMax
|
||||
};
|
||||
|
||||
virtual void setProperty(int idx, Property *prop);
|
||||
Property *getProperty(int idx);
|
||||
Property *getProperty(const char *);
|
||||
virtual void setProperty(int idx, Property* prop);
|
||||
Property* getProperty(int idx);
|
||||
Property* getProperty(const char*);
|
||||
|
||||
struct PropInfo {
|
||||
struct PropInfo
|
||||
{
|
||||
int index;
|
||||
const char *name;
|
||||
const char* name;
|
||||
Base::Type type;
|
||||
const char *doc;
|
||||
const char* doc;
|
||||
|
||||
PropInfo(int index, const char *name,Base::Type type,const char *doc)
|
||||
: index(index), name(name), type(type), doc(doc)
|
||||
PropInfo(int index, const char* name, Base::Type type, const char* doc)
|
||||
: index(index)
|
||||
, name(name)
|
||||
, type(type)
|
||||
, doc(doc)
|
||||
{}
|
||||
|
||||
PropInfo() : index(0), name(nullptr), doc(nullptr) {}
|
||||
PropInfo()
|
||||
: index(0)
|
||||
, name(nullptr)
|
||||
, doc(nullptr)
|
||||
{}
|
||||
};
|
||||
|
||||
#define LINK_PROP_INFO(_1,_var,_param) \
|
||||
_var.push_back(PropInfo(BOOST_PP_CAT(Prop,LINK_PNAME(_param)),\
|
||||
BOOST_PP_STRINGIZE(LINK_PNAME(_param)),\
|
||||
LINK_PPTYPE(_param)::getClassTypeId(), \
|
||||
LINK_PDOC(_param)));
|
||||
#define LINK_PROP_INFO(_1, _var, _param) \
|
||||
_var.push_back(PropInfo(BOOST_PP_CAT(Prop, LINK_PNAME(_param)), \
|
||||
BOOST_PP_STRINGIZE(LINK_PNAME(_param)), \
|
||||
LINK_PPTYPE(_param)::getClassTypeId(), \
|
||||
LINK_PDOC(_param)));
|
||||
|
||||
virtual const std::vector<PropInfo> &getPropertyInfo() const;
|
||||
virtual const std::vector<PropInfo>& getPropertyInfo() const;
|
||||
|
||||
using PropInfoMap = std::map<std::string, PropInfo>;
|
||||
virtual const PropInfoMap &getPropertyInfoMap() const;
|
||||
virtual const PropInfoMap& getPropertyInfoMap() const;
|
||||
|
||||
enum LinkCopyOnChangeType {
|
||||
enum LinkCopyOnChangeType
|
||||
{
|
||||
CopyOnChangeDisabled = 0,
|
||||
CopyOnChangeEnabled = 1,
|
||||
CopyOnChangeOwned = 2,
|
||||
CopyOnChangeTracking = 3
|
||||
};
|
||||
|
||||
#define LINK_PROP_GET(_1,_2,_param) \
|
||||
LINK_PTYPE(_param) BOOST_PP_SEQ_CAT((get)(LINK_PNAME(_param))(Value)) () const {\
|
||||
auto prop = props[LINK_PINDEX(_param)];\
|
||||
if(!prop) return LINK_PDEF(_param);\
|
||||
return static_cast<const LINK_PPTYPE(_param) *>(prop)->getValue();\
|
||||
}\
|
||||
const LINK_PPTYPE(_param) *BOOST_PP_SEQ_CAT((get)(LINK_PNAME(_param))(Property)) () const {\
|
||||
auto prop = props[LINK_PINDEX(_param)];\
|
||||
return static_cast<const LINK_PPTYPE(_param) *>(prop);\
|
||||
}\
|
||||
LINK_PPTYPE(_param) *BOOST_PP_SEQ_CAT((get)(LINK_PNAME(_param))(Property)) () {\
|
||||
auto prop = props[LINK_PINDEX(_param)];\
|
||||
return static_cast<LINK_PPTYPE(_param) *>(prop);\
|
||||
}\
|
||||
#define LINK_PROP_GET(_1, _2, _param) \
|
||||
LINK_PTYPE(_param) BOOST_PP_SEQ_CAT((get)(LINK_PNAME(_param))(Value))() const \
|
||||
{ \
|
||||
auto prop = props[LINK_PINDEX(_param)]; \
|
||||
if (!prop) \
|
||||
return LINK_PDEF(_param); \
|
||||
return static_cast<const LINK_PPTYPE(_param)*>(prop)->getValue(); \
|
||||
} \
|
||||
const LINK_PPTYPE(_param) * BOOST_PP_SEQ_CAT((get)(LINK_PNAME(_param))(Property))() const \
|
||||
{ \
|
||||
auto prop = props[LINK_PINDEX(_param)]; \
|
||||
return static_cast<const LINK_PPTYPE(_param)*>(prop); \
|
||||
} \
|
||||
LINK_PPTYPE(_param) * BOOST_PP_SEQ_CAT((get)(LINK_PNAME(_param))(Property))() \
|
||||
{ \
|
||||
auto prop = props[LINK_PINDEX(_param)]; \
|
||||
return static_cast<LINK_PPTYPE(_param)*>(prop); \
|
||||
}
|
||||
|
||||
// defines get##Name##Property() and get##Name##Value() accessor
|
||||
BOOST_PP_SEQ_FOR_EACH(LINK_PROP_GET,_,LINK_PARAMS)
|
||||
BOOST_PP_SEQ_FOR_EACH(LINK_PROP_GET, _, LINK_PARAMS)
|
||||
|
||||
PropertyLinkList *_getElementListProperty() const;
|
||||
const std::vector<App::DocumentObject*> &_getElementListValue() const;
|
||||
PropertyLinkList* _getElementListProperty() const;
|
||||
const std::vector<App::DocumentObject*>& _getElementListValue() const;
|
||||
|
||||
PropertyBool *_getShowElementProperty() const;
|
||||
PropertyBool* _getShowElementProperty() const;
|
||||
bool _getShowElementValue() const;
|
||||
|
||||
PropertyInteger *_getElementCountProperty() const;
|
||||
PropertyInteger* _getElementCountProperty() const;
|
||||
int _getElementCountValue() const;
|
||||
|
||||
std::vector<DocumentObject*> getLinkedChildren(bool filter=true) const;
|
||||
std::vector<DocumentObject*> getLinkedChildren(bool filter = true) const;
|
||||
|
||||
const char *flattenSubname(const char *subname) const;
|
||||
void expandSubname(std::string &subname) const;
|
||||
const char* flattenSubname(const char* subname) const;
|
||||
void expandSubname(std::string& subname) const;
|
||||
|
||||
DocumentObject *getLink(int depth=0) const;
|
||||
DocumentObject* getLink(int depth = 0) const;
|
||||
|
||||
Base::Matrix4D getTransform(bool transform) const;
|
||||
Base::Vector3d getScaleVector() const;
|
||||
|
||||
App::GroupExtension *linkedPlainGroup() const;
|
||||
App::GroupExtension* linkedPlainGroup() const;
|
||||
|
||||
bool linkTransform() const;
|
||||
|
||||
const char *getSubName() const {
|
||||
const char* getSubName() const
|
||||
{
|
||||
parseSubName();
|
||||
return !mySubName.empty()?mySubName.c_str():nullptr;
|
||||
return !mySubName.empty() ? mySubName.c_str() : nullptr;
|
||||
}
|
||||
|
||||
const std::vector<std::string> &getSubElements() const {
|
||||
const std::vector<std::string>& getSubElements() const
|
||||
{
|
||||
parseSubName();
|
||||
return mySubElements;
|
||||
}
|
||||
|
||||
bool extensionGetSubObject(DocumentObject *&ret, const char *subname,
|
||||
PyObject **pyObj=nullptr, Base::Matrix4D *mat=nullptr, bool transform=false, int depth=0) const override;
|
||||
bool extensionGetSubObject(DocumentObject*& ret,
|
||||
const char* subname,
|
||||
PyObject** pyObj = nullptr,
|
||||
Base::Matrix4D* mat = nullptr,
|
||||
bool transform = false,
|
||||
int depth = 0) const override;
|
||||
|
||||
bool extensionGetSubObjects(std::vector<std::string>&ret, int reason) const override;
|
||||
bool extensionGetSubObjects(std::vector<std::string>& ret, int reason) const override;
|
||||
|
||||
bool extensionGetLinkedObject(DocumentObject *&ret,
|
||||
bool recurse, Base::Matrix4D *mat, bool transform, int depth) const override;
|
||||
bool extensionGetLinkedObject(DocumentObject*& ret,
|
||||
bool recurse,
|
||||
Base::Matrix4D* mat,
|
||||
bool transform,
|
||||
int depth) const override;
|
||||
|
||||
App::DocumentObjectExecReturn *extensionExecute() override;
|
||||
App::DocumentObjectExecReturn* extensionExecute() override;
|
||||
short extensionMustExecute() override;
|
||||
void extensionOnChanged(const Property* p) override;
|
||||
void onExtendedUnsetupObject () override;
|
||||
void onExtendedUnsetupObject() override;
|
||||
void onExtendedDocumentRestored() override;
|
||||
|
||||
int extensionSetElementVisible(const char *, bool) override;
|
||||
int extensionIsElementVisible(const char *) override;
|
||||
int extensionSetElementVisible(const char*, bool) override;
|
||||
int extensionIsElementVisible(const char*) override;
|
||||
bool extensionHasChildElement() const override;
|
||||
|
||||
PyObject* getExtensionPyObject() override;
|
||||
|
||||
Property *extensionGetPropertyByName(const char* name) const override;
|
||||
Property* extensionGetPropertyByName(const char* name) const override;
|
||||
|
||||
static int getArrayIndex(const char *subname, const char **psubname=nullptr);
|
||||
int getElementIndex(const char *subname, const char **psubname=nullptr) const;
|
||||
void elementNameFromIndex(int idx, std::ostream &ss) const;
|
||||
static int getArrayIndex(const char* subname, const char** psubname = nullptr);
|
||||
int getElementIndex(const char* subname, const char** psubname = nullptr) const;
|
||||
void elementNameFromIndex(int idx, std::ostream& ss) const;
|
||||
|
||||
DocumentObject *getContainer();
|
||||
const DocumentObject *getContainer() const;
|
||||
DocumentObject* getContainer();
|
||||
const DocumentObject* getContainer() const;
|
||||
|
||||
void setLink(int index, DocumentObject *obj, const char *subname=nullptr,
|
||||
const std::vector<std::string> &subs = std::vector<std::string>());
|
||||
void setLink(int index,
|
||||
DocumentObject* obj,
|
||||
const char* subname = nullptr,
|
||||
const std::vector<std::string>& subs = std::vector<std::string>());
|
||||
|
||||
DocumentObject *getTrueLinkedObject(bool recurse,
|
||||
Base::Matrix4D *mat=nullptr,int depth=0, bool noElement=false) const;
|
||||
DocumentObject* getTrueLinkedObject(bool recurse,
|
||||
Base::Matrix4D* mat = nullptr,
|
||||
int depth = 0,
|
||||
bool noElement = false) const;
|
||||
|
||||
using LinkPropMap = std::map<const Property*,std::pair<LinkBaseExtension*,int> >;
|
||||
using LinkPropMap = std::map<const Property*, std::pair<LinkBaseExtension*, int>>;
|
||||
|
||||
bool hasPlacement() const {
|
||||
bool hasPlacement() const
|
||||
{
|
||||
return getLinkPlacementProperty() || getPlacementProperty();
|
||||
}
|
||||
|
||||
void cacheChildLabel(int enable=-1) const;
|
||||
void cacheChildLabel(int enable = -1) const;
|
||||
|
||||
static bool setupCopyOnChange(App::DocumentObject *obj, App::DocumentObject *linked,
|
||||
std::vector<boost::signals2::scoped_connection> *copyOnChangeConns, bool checkExisting);
|
||||
static bool
|
||||
setupCopyOnChange(App::DocumentObject* obj,
|
||||
App::DocumentObject* linked,
|
||||
std::vector<boost::signals2::scoped_connection>* copyOnChangeConns,
|
||||
bool checkExisting);
|
||||
|
||||
static bool isCopyOnChangeProperty(App::DocumentObject *obj, const Property &prop);
|
||||
static bool isCopyOnChangeProperty(App::DocumentObject* obj, const Property& prop);
|
||||
|
||||
void syncCopyOnChange();
|
||||
|
||||
/** Options used in setOnChangeCopyObject()
|
||||
* Multiple options can be combined by bitwise or operator
|
||||
*/
|
||||
enum class OnChangeCopyOptions {
|
||||
enum class OnChangeCopyOptions
|
||||
{
|
||||
/// No options set
|
||||
None = 0,
|
||||
/// If set, then exclude the input from object list to copy on change, or else, include the input object.
|
||||
/// If set, then exclude the input from object list to copy on change, or else, include the
|
||||
/// input object.
|
||||
Exclude = 1,
|
||||
/// If set , then apply the setting to all links to the input object, or else, apply only to this link.
|
||||
/// If set , then apply the setting to all links to the input object, or else, apply only to
|
||||
/// this link.
|
||||
ApplyAll = 2,
|
||||
};
|
||||
|
||||
@@ -344,53 +444,55 @@ public:
|
||||
* @param obj: input object
|
||||
* @param options: control options. @sa OnChangeCopyOptions.
|
||||
*/
|
||||
void setOnChangeCopyObject(App::DocumentObject *obj, OnChangeCopyOptions options);
|
||||
void setOnChangeCopyObject(App::DocumentObject* obj, OnChangeCopyOptions options);
|
||||
|
||||
std::vector<App::DocumentObject *> getOnChangeCopyObjects(
|
||||
std::vector<App::DocumentObject *> *excludes = nullptr,
|
||||
App::DocumentObject *src = nullptr);
|
||||
std::vector<App::DocumentObject*>
|
||||
getOnChangeCopyObjects(std::vector<App::DocumentObject*>* excludes = nullptr,
|
||||
App::DocumentObject* src = nullptr);
|
||||
|
||||
bool isLinkedToConfigurableObject() const;
|
||||
|
||||
void monitorOnChangeCopyObjects(const std::vector<App::DocumentObject*> &objs);
|
||||
void monitorOnChangeCopyObjects(const std::vector<App::DocumentObject*>& objs);
|
||||
|
||||
/// Check if the linked object is a copy on change
|
||||
bool isLinkMutated() const;
|
||||
|
||||
protected:
|
||||
void _handleChangedPropertyName(Base::XMLReader &reader,
|
||||
const char * TypeName, const char *PropName);
|
||||
void
|
||||
_handleChangedPropertyName(Base::XMLReader& reader, const char* TypeName, const char* PropName);
|
||||
void parseSubName() const;
|
||||
void update(App::DocumentObject *parent, const Property *prop);
|
||||
void checkCopyOnChange(App::DocumentObject *parent, const App::Property &prop);
|
||||
void setupCopyOnChange(App::DocumentObject *parent, bool checkSource = false);
|
||||
App::DocumentObject *makeCopyOnChange();
|
||||
void update(App::DocumentObject* parent, const Property* prop);
|
||||
void checkCopyOnChange(App::DocumentObject* parent, const App::Property& prop);
|
||||
void setupCopyOnChange(App::DocumentObject* parent, bool checkSource = false);
|
||||
App::DocumentObject* makeCopyOnChange();
|
||||
void syncElementList();
|
||||
void detachElement(App::DocumentObject *obj);
|
||||
void detachElement(App::DocumentObject* obj);
|
||||
void detachElements();
|
||||
void checkGeoElementMap(const App::DocumentObject *obj,
|
||||
const App::DocumentObject *linked, PyObject **pyObj, const char *postfix) const;
|
||||
void checkGeoElementMap(const App::DocumentObject* obj,
|
||||
const App::DocumentObject* linked,
|
||||
PyObject** pyObj,
|
||||
const char* postfix) const;
|
||||
void updateGroup();
|
||||
void slotChangedPlainGroup(const App::DocumentObject &, const App::Property &);
|
||||
void slotChangedPlainGroup(const App::DocumentObject&, const App::Property&);
|
||||
|
||||
protected:
|
||||
std::vector<Property *> props;
|
||||
std::vector<Property*> props;
|
||||
std::unordered_set<const App::DocumentObject*> myHiddenElements;
|
||||
mutable std::vector<std::string> mySubElements;
|
||||
mutable std::string mySubName;
|
||||
|
||||
std::unordered_map<const App::DocumentObject*,
|
||||
boost::signals2::scoped_connection> plainGroupConns;
|
||||
std::unordered_map<const App::DocumentObject*, boost::signals2::scoped_connection>
|
||||
plainGroupConns;
|
||||
|
||||
long prevLinkedObjectID = 0;
|
||||
|
||||
mutable std::unordered_map<std::string,int> myLabelCache; // for label based subname lookup
|
||||
mutable bool enableLabelCache{false};
|
||||
bool hasOldSubElement{false};
|
||||
mutable std::unordered_map<std::string, int> myLabelCache; // for label based subname lookup
|
||||
mutable bool enableLabelCache {false};
|
||||
bool hasOldSubElement {false};
|
||||
|
||||
std::vector<boost::signals2::scoped_connection> copyOnChangeConns;
|
||||
std::vector<boost::signals2::scoped_connection> copyOnChangeSrcConns;
|
||||
bool hasCopyOnChange{true};
|
||||
bool hasCopyOnChange {true};
|
||||
|
||||
mutable bool checkingProperty = false;
|
||||
bool pauseCopyOnChange = false;
|
||||
@@ -404,7 +506,7 @@ using LinkBaseExtensionPython = ExtensionPythonT<LinkBaseExtension>;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class AppExport LinkExtension : public LinkBaseExtension
|
||||
class AppExport LinkExtension: public LinkBaseExtension
|
||||
{
|
||||
EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(App::LinkExtension);
|
||||
using inherited = LinkBaseExtension;
|
||||
@@ -428,36 +530,36 @@ public:
|
||||
*/
|
||||
//@{
|
||||
|
||||
#define LINK_ENAME(_param) BOOST_PP_TUPLE_ELEM(5,_param)
|
||||
#define LINK_ETYPE(_param) BOOST_PP_TUPLE_ELEM(6,_param)
|
||||
#define LINK_EPTYPE(_param) BOOST_PP_TUPLE_ELEM(7,_param)
|
||||
#define LINK_EGROUP(_param) BOOST_PP_TUPLE_ELEM(8,_param)
|
||||
#define LINK_ENAME(_param) BOOST_PP_TUPLE_ELEM(5, _param)
|
||||
#define LINK_ETYPE(_param) BOOST_PP_TUPLE_ELEM(6, _param)
|
||||
#define LINK_EPTYPE(_param) BOOST_PP_TUPLE_ELEM(7, _param)
|
||||
#define LINK_EGROUP(_param) BOOST_PP_TUPLE_ELEM(8, _param)
|
||||
|
||||
#define _LINK_PROP_ADD(_add_property, _param) \
|
||||
_add_property(BOOST_PP_STRINGIZE(LINK_ENAME(_param)),LINK_ENAME(_param),\
|
||||
(LINK_PDEF(_param)),LINK_EGROUP(_param),LINK_EPTYPE(_param),LINK_PDOC(_param));\
|
||||
setProperty(LINK_PINDEX(_param),&LINK_ENAME(_param));
|
||||
#define _LINK_PROP_ADD(_add_property, _param) \
|
||||
_add_property(BOOST_PP_STRINGIZE(LINK_ENAME(_param)), \
|
||||
LINK_ENAME(_param), \
|
||||
(LINK_PDEF(_param)), \
|
||||
LINK_EGROUP(_param), \
|
||||
LINK_EPTYPE(_param), \
|
||||
LINK_PDOC(_param)); \
|
||||
setProperty(LINK_PINDEX(_param), &LINK_ENAME(_param));
|
||||
|
||||
#define LINK_PROP_ADD(_1,_2,_param) \
|
||||
_LINK_PROP_ADD(_ADD_PROPERTY_TYPE,_param);
|
||||
#define LINK_PROP_ADD(_1, _2, _param) _LINK_PROP_ADD(_ADD_PROPERTY_TYPE, _param);
|
||||
|
||||
#define LINK_PROP_ADD_EXTENSION(_1,_2,_param) \
|
||||
_LINK_PROP_ADD(_EXTENSION_ADD_PROPERTY_TYPE,_param);
|
||||
#define LINK_PROP_ADD_EXTENSION(_1, _2, _param) \
|
||||
_LINK_PROP_ADD(_EXTENSION_ADD_PROPERTY_TYPE, _param);
|
||||
|
||||
#define LINK_PROPS_ADD(_seq) \
|
||||
BOOST_PP_SEQ_FOR_EACH(LINK_PROP_ADD,_,_seq)
|
||||
#define LINK_PROPS_ADD(_seq) BOOST_PP_SEQ_FOR_EACH(LINK_PROP_ADD, _, _seq)
|
||||
|
||||
#define LINK_PROPS_ADD_EXTENSION(_seq) \
|
||||
BOOST_PP_SEQ_FOR_EACH(LINK_PROP_ADD_EXTENSION,_,_seq)
|
||||
#define LINK_PROPS_ADD_EXTENSION(_seq) BOOST_PP_SEQ_FOR_EACH(LINK_PROP_ADD_EXTENSION, _, _seq)
|
||||
|
||||
#define _LINK_PROP_SET(_1,_2,_param) \
|
||||
setProperty(LINK_PINDEX(_param),&LINK_ENAME(_param));
|
||||
#define _LINK_PROP_SET(_1, _2, _param) setProperty(LINK_PINDEX(_param), &LINK_ENAME(_param));
|
||||
|
||||
#define LINK_PROPS_SET(_seq) BOOST_PP_SEQ_FOR_EACH(_LINK_PROP_SET,_,_seq)
|
||||
#define LINK_PROPS_SET(_seq) BOOST_PP_SEQ_FOR_EACH(_LINK_PROP_SET, _, _seq)
|
||||
|
||||
/// Helper for defining default extended parameter
|
||||
#define _LINK_PARAM_EXT(_name,_type,_ptype,_def,_doc,...) \
|
||||
((_name,_type,_ptype,_def,_doc,_name,_ptype,App::Prop_None," Link"))
|
||||
#define _LINK_PARAM_EXT(_name, _type, _ptype, _def, _doc, ...) \
|
||||
((_name, _type, _ptype, _def, _doc, _name, _ptype, App::Prop_None, " Link"))
|
||||
|
||||
/** Define default extended parameter
|
||||
* It simply reuses Name as Property_Name, Property_Type as
|
||||
@@ -466,44 +568,46 @@ public:
|
||||
#define LINK_PARAM_EXT(_param) BOOST_PP_EXPAND(_LINK_PARAM_EXT LINK_PARAM_##_param())
|
||||
|
||||
/// Helper for extended parameter with app property type
|
||||
#define _LINK_PARAM_EXT_ATYPE(_name,_type,_ptype,_def,_doc,_atype) \
|
||||
((_name,_type,_ptype,_def,_doc,_name,_ptype,_atype," Link"))
|
||||
#define _LINK_PARAM_EXT_ATYPE(_name, _type, _ptype, _def, _doc, _atype) \
|
||||
((_name, _type, _ptype, _def, _doc, _name, _ptype, _atype, " Link"))
|
||||
|
||||
/// Define extended parameter with app property type
|
||||
#define LINK_PARAM_EXT_ATYPE(_param,_atype) \
|
||||
#define LINK_PARAM_EXT_ATYPE(_param, _atype) \
|
||||
BOOST_PP_EXPAND(_LINK_PARAM_EXT_ATYPE LINK_PARAM_##_param(_atype))
|
||||
|
||||
/// Helper for extended parameter with derived property type
|
||||
#define _LINK_PARAM_EXT_TYPE(_name,_type,_ptype,_def,_doc,_dtype) \
|
||||
((_name,_type,_ptype,_def,_doc,_name,_dtype,App::Prop_None," Link"))
|
||||
#define _LINK_PARAM_EXT_TYPE(_name, _type, _ptype, _def, _doc, _dtype) \
|
||||
((_name, _type, _ptype, _def, _doc, _name, _dtype, App::Prop_None, " Link"))
|
||||
|
||||
/// Define extended parameter with derived property type
|
||||
#define LINK_PARAM_EXT_TYPE(_param,_dtype) \
|
||||
#define LINK_PARAM_EXT_TYPE(_param, _dtype) \
|
||||
BOOST_PP_EXPAND(_LINK_PARAM_EXT_TYPE LINK_PARAM_##_param(_dtype))
|
||||
|
||||
/// Helper for extended parameter with a different property name
|
||||
#define _LINK_PARAM_EXT_NAME(_name,_type,_ptype,_def,_doc,_pname) \
|
||||
((_name,_type,_ptype,_def,_doc,_pname,_ptype,App::Prop_None," Link"))
|
||||
#define _LINK_PARAM_EXT_NAME(_name, _type, _ptype, _def, _doc, _pname) \
|
||||
((_name, _type, _ptype, _def, _doc, _pname, _ptype, App::Prop_None, " Link"))
|
||||
|
||||
/// Define extended parameter with a different property name
|
||||
#define LINK_PARAM_EXT_NAME(_param,_pname) BOOST_PP_EXPAND(_LINK_PARAM_EXT_NAME LINK_PARAM_##_param(_pname))
|
||||
#define LINK_PARAM_EXT_NAME(_param, _pname) \
|
||||
BOOST_PP_EXPAND(_LINK_PARAM_EXT_NAME LINK_PARAM_##_param(_pname))
|
||||
//@}
|
||||
|
||||
#define LINK_PARAMS_EXT \
|
||||
LINK_PARAM_EXT(SCALE)\
|
||||
LINK_PARAM_EXT_ATYPE(SCALE_VECTOR,App::Prop_Hidden)\
|
||||
LINK_PARAM_EXT(SCALES)\
|
||||
LINK_PARAM_EXT(VISIBILITIES)\
|
||||
LINK_PARAM_EXT(PLACEMENTS)\
|
||||
#define LINK_PARAMS_EXT \
|
||||
LINK_PARAM_EXT(SCALE) \
|
||||
LINK_PARAM_EXT_ATYPE(SCALE_VECTOR, App::Prop_Hidden) \
|
||||
LINK_PARAM_EXT(SCALES) \
|
||||
LINK_PARAM_EXT(VISIBILITIES) \
|
||||
LINK_PARAM_EXT(PLACEMENTS) \
|
||||
LINK_PARAM_EXT(ELEMENTS)
|
||||
|
||||
#define LINK_PROP_DEFINE(_1,_2,_param) LINK_ETYPE(_param) LINK_ENAME(_param);
|
||||
#define LINK_PROPS_DEFINE(_seq) BOOST_PP_SEQ_FOR_EACH(LINK_PROP_DEFINE,_,_seq)
|
||||
#define LINK_PROP_DEFINE(_1, _2, _param) LINK_ETYPE(_param) LINK_ENAME(_param);
|
||||
#define LINK_PROPS_DEFINE(_seq) BOOST_PP_SEQ_FOR_EACH(LINK_PROP_DEFINE, _, _seq)
|
||||
|
||||
// defines the actual properties
|
||||
LINK_PROPS_DEFINE(LINK_PARAMS_EXT)
|
||||
|
||||
void onExtendedDocumentRestored() override {
|
||||
void onExtendedDocumentRestored() override
|
||||
{
|
||||
LINK_PROPS_SET(LINK_PARAMS_EXT);
|
||||
inherited::onExtendedDocumentRestored();
|
||||
}
|
||||
@@ -515,44 +619,47 @@ using LinkExtensionPython = ExtensionPythonT<LinkExtension>;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class AppExport Link : public App::DocumentObject, public App::LinkExtension
|
||||
class AppExport Link: public App::DocumentObject, public App::LinkExtension
|
||||
{
|
||||
PROPERTY_HEADER_WITH_EXTENSIONS(App::Link);
|
||||
using inherited = App::DocumentObject;
|
||||
public:
|
||||
|
||||
#define LINK_PARAMS_LINK \
|
||||
LINK_PARAM_EXT_TYPE(OBJECT, App::PropertyXLink)\
|
||||
LINK_PARAM_EXT(CLAIM_CHILD)\
|
||||
LINK_PARAM_EXT(TRANSFORM)\
|
||||
LINK_PARAM_EXT(LINK_PLACEMENT)\
|
||||
LINK_PARAM_EXT(PLACEMENT)\
|
||||
LINK_PARAM_EXT(SHOW_ELEMENT)\
|
||||
LINK_PARAM_EXT_TYPE(COUNT,App::PropertyIntegerConstraint)\
|
||||
LINK_PARAM_EXT(LINK_EXECUTE)\
|
||||
LINK_PARAM_EXT_ATYPE(COLORED_ELEMENTS,App::Prop_Hidden)\
|
||||
LINK_PARAM_EXT(COPY_ON_CHANGE)\
|
||||
LINK_PARAM_EXT_TYPE(COPY_ON_CHANGE_SOURCE, App::PropertyXLink)\
|
||||
LINK_PARAM_EXT(COPY_ON_CHANGE_GROUP)\
|
||||
LINK_PARAM_EXT(COPY_ON_CHANGE_TOUCHED)\
|
||||
public:
|
||||
#define LINK_PARAMS_LINK \
|
||||
LINK_PARAM_EXT_TYPE(OBJECT, App::PropertyXLink) \
|
||||
LINK_PARAM_EXT(CLAIM_CHILD) \
|
||||
LINK_PARAM_EXT(TRANSFORM) \
|
||||
LINK_PARAM_EXT(LINK_PLACEMENT) \
|
||||
LINK_PARAM_EXT(PLACEMENT) \
|
||||
LINK_PARAM_EXT(SHOW_ELEMENT) \
|
||||
LINK_PARAM_EXT_TYPE(COUNT, App::PropertyIntegerConstraint) \
|
||||
LINK_PARAM_EXT(LINK_EXECUTE) \
|
||||
LINK_PARAM_EXT_ATYPE(COLORED_ELEMENTS, App::Prop_Hidden) \
|
||||
LINK_PARAM_EXT(COPY_ON_CHANGE) \
|
||||
LINK_PARAM_EXT_TYPE(COPY_ON_CHANGE_SOURCE, App::PropertyXLink) \
|
||||
LINK_PARAM_EXT(COPY_ON_CHANGE_GROUP) \
|
||||
LINK_PARAM_EXT(COPY_ON_CHANGE_TOUCHED)
|
||||
|
||||
LINK_PROPS_DEFINE(LINK_PARAMS_LINK)
|
||||
|
||||
Link();
|
||||
|
||||
const char* getViewProviderName() const override{
|
||||
const char* getViewProviderName() const override
|
||||
{
|
||||
return "Gui::ViewProviderLink";
|
||||
}
|
||||
|
||||
void onDocumentRestored() override {
|
||||
void onDocumentRestored() override
|
||||
{
|
||||
LINK_PROPS_SET(LINK_PARAMS_LINK);
|
||||
inherited::onDocumentRestored();
|
||||
}
|
||||
|
||||
void handleChangedPropertyName(Base::XMLReader &reader,
|
||||
const char * TypeName, const char *PropName) override
|
||||
void handleChangedPropertyName(Base::XMLReader& reader,
|
||||
const char* TypeName,
|
||||
const char* PropName) override
|
||||
{
|
||||
_handleChangedPropertyName(reader,TypeName,PropName);
|
||||
_handleChangedPropertyName(reader, TypeName, PropName);
|
||||
}
|
||||
|
||||
bool canLinkProperties() const override;
|
||||
@@ -566,42 +673,46 @@ using LinkPython = App::FeaturePythonT<Link>;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class AppExport LinkElement : public App::DocumentObject, public App::LinkBaseExtension {
|
||||
class AppExport LinkElement: public App::DocumentObject, public App::LinkBaseExtension
|
||||
{
|
||||
PROPERTY_HEADER_WITH_EXTENSIONS(App::LinkElement);
|
||||
using inherited = App::DocumentObject;
|
||||
public:
|
||||
|
||||
#define LINK_PARAMS_ELEMENT \
|
||||
LINK_PARAM_EXT(SCALE)\
|
||||
LINK_PARAM_EXT_ATYPE(SCALE_VECTOR,App::Prop_Hidden)\
|
||||
LINK_PARAM_EXT_TYPE(OBJECT, App::PropertyXLink)\
|
||||
LINK_PARAM_EXT(TRANSFORM) \
|
||||
LINK_PARAM_EXT(LINK_PLACEMENT)\
|
||||
LINK_PARAM_EXT(PLACEMENT)\
|
||||
LINK_PARAM_EXT(COPY_ON_CHANGE)\
|
||||
LINK_PARAM_EXT_TYPE(COPY_ON_CHANGE_SOURCE, App::PropertyXLink)\
|
||||
LINK_PARAM_EXT(COPY_ON_CHANGE_GROUP)\
|
||||
LINK_PARAM_EXT(COPY_ON_CHANGE_TOUCHED)\
|
||||
public:
|
||||
#define LINK_PARAMS_ELEMENT \
|
||||
LINK_PARAM_EXT(SCALE) \
|
||||
LINK_PARAM_EXT_ATYPE(SCALE_VECTOR, App::Prop_Hidden) \
|
||||
LINK_PARAM_EXT_TYPE(OBJECT, App::PropertyXLink) \
|
||||
LINK_PARAM_EXT(TRANSFORM) \
|
||||
LINK_PARAM_EXT(LINK_PLACEMENT) \
|
||||
LINK_PARAM_EXT(PLACEMENT) \
|
||||
LINK_PARAM_EXT(COPY_ON_CHANGE) \
|
||||
LINK_PARAM_EXT_TYPE(COPY_ON_CHANGE_SOURCE, App::PropertyXLink) \
|
||||
LINK_PARAM_EXT(COPY_ON_CHANGE_GROUP) \
|
||||
LINK_PARAM_EXT(COPY_ON_CHANGE_TOUCHED)
|
||||
|
||||
// defines the actual properties
|
||||
LINK_PROPS_DEFINE(LINK_PARAMS_ELEMENT)
|
||||
|
||||
LinkElement();
|
||||
const char* getViewProviderName() const override{
|
||||
const char* getViewProviderName() const override
|
||||
{
|
||||
return "Gui::ViewProviderLink";
|
||||
}
|
||||
|
||||
void onDocumentRestored() override {
|
||||
void onDocumentRestored() override
|
||||
{
|
||||
LINK_PROPS_SET(LINK_PARAMS_ELEMENT);
|
||||
inherited::onDocumentRestored();
|
||||
}
|
||||
|
||||
bool canDelete() const;
|
||||
|
||||
void handleChangedPropertyName(Base::XMLReader &reader,
|
||||
const char * TypeName, const char *PropName) override
|
||||
void handleChangedPropertyName(Base::XMLReader& reader,
|
||||
const char* TypeName,
|
||||
const char* PropName) override
|
||||
{
|
||||
_handleChangedPropertyName(reader,TypeName,PropName);
|
||||
_handleChangedPropertyName(reader, TypeName, PropName);
|
||||
}
|
||||
|
||||
bool isLink() const override;
|
||||
@@ -613,28 +724,31 @@ using LinkElementPython = App::FeaturePythonT<LinkElement>;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class AppExport LinkGroup : public App::DocumentObject, public App::LinkBaseExtension {
|
||||
class AppExport LinkGroup: public App::DocumentObject, public App::LinkBaseExtension
|
||||
{
|
||||
PROPERTY_HEADER_WITH_EXTENSIONS(App::LinkGroup);
|
||||
using inherited = App::DocumentObject;
|
||||
public:
|
||||
|
||||
#define LINK_PARAMS_GROUP \
|
||||
LINK_PARAM_EXT(ELEMENTS)\
|
||||
LINK_PARAM_EXT(PLACEMENT)\
|
||||
LINK_PARAM_EXT(VISIBILITIES)\
|
||||
LINK_PARAM_EXT(MODE)\
|
||||
LINK_PARAM_EXT_ATYPE(COLORED_ELEMENTS,App::Prop_Hidden)
|
||||
public:
|
||||
#define LINK_PARAMS_GROUP \
|
||||
LINK_PARAM_EXT(ELEMENTS) \
|
||||
LINK_PARAM_EXT(PLACEMENT) \
|
||||
LINK_PARAM_EXT(VISIBILITIES) \
|
||||
LINK_PARAM_EXT(MODE) \
|
||||
LINK_PARAM_EXT_ATYPE(COLORED_ELEMENTS, App::Prop_Hidden)
|
||||
|
||||
// defines the actual properties
|
||||
LINK_PROPS_DEFINE(LINK_PARAMS_GROUP)
|
||||
|
||||
LinkGroup();
|
||||
|
||||
const char* getViewProviderName() const override{
|
||||
const char* getViewProviderName() const override
|
||||
{
|
||||
return "Gui::ViewProviderLink";
|
||||
}
|
||||
|
||||
void onDocumentRestored() override {
|
||||
void onDocumentRestored() override
|
||||
{
|
||||
LINK_PROPS_SET(LINK_PARAMS_GROUP);
|
||||
inherited::onDocumentRestored();
|
||||
}
|
||||
@@ -642,7 +756,7 @@ public:
|
||||
|
||||
using LinkGroupPython = App::FeaturePythonT<LinkGroup>;
|
||||
|
||||
} //namespace App
|
||||
} // namespace App
|
||||
|
||||
ENABLE_BITMASK_OPERATORS(App::Link::OnChangeCopyOptions)
|
||||
|
||||
@@ -651,7 +765,8 @@ import LinkParams
|
||||
LinkParams.declare()
|
||||
]]]*/
|
||||
|
||||
namespace App {
|
||||
namespace App
|
||||
{
|
||||
/** Convenient class to obtain App::Link related parameters
|
||||
|
||||
* The parameters are under group "User parameter:BaseApp/Preferences/Link"
|
||||
@@ -682,7 +797,8 @@ namespace App {
|
||||
* void LinkParams:on<parameter_name>Changed()
|
||||
* @endcode
|
||||
*/
|
||||
class AppExport LinkParams {
|
||||
class AppExport LinkParams
|
||||
{
|
||||
public:
|
||||
static ParameterGrp::handle getHandle();
|
||||
|
||||
@@ -691,21 +807,21 @@ public:
|
||||
///
|
||||
/// Stores the last user choice of whether to apply CopyOnChange setup to all link
|
||||
/// that links to the same configurable object
|
||||
static const bool & getCopyOnChangeApplyToAll();
|
||||
static const bool & defaultCopyOnChangeApplyToAll();
|
||||
static const bool& getCopyOnChangeApplyToAll();
|
||||
static const bool& defaultCopyOnChangeApplyToAll();
|
||||
static void removeCopyOnChangeApplyToAll();
|
||||
static void setCopyOnChangeApplyToAll(const bool &v);
|
||||
static const char *docCopyOnChangeApplyToAll();
|
||||
static void setCopyOnChangeApplyToAll(const bool& v);
|
||||
static const char* docCopyOnChangeApplyToAll();
|
||||
//@}
|
||||
|
||||
// Auto generated code. See class document of LinkParams.
|
||||
};
|
||||
} // namespace App
|
||||
} // namespace App
|
||||
//[[[end]]]
|
||||
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // APP_LINK_H
|
||||
#endif // APP_LINK_H
|
||||
|
||||
+143
-104
@@ -23,7 +23,7 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
#include "DocumentObjectPy.h"
|
||||
@@ -40,155 +40,167 @@ std::string LinkBaseExtensionPy::representation() const
|
||||
return str.str();
|
||||
}
|
||||
|
||||
using PropTmpMap = std::map<std::string, std::pair<int,Property*> >;
|
||||
using PropTmpMap = std::map<std::string, std::pair<int, Property*>>;
|
||||
using PropMap = std::map<std::string, Property*>;
|
||||
|
||||
static bool getProperty(PropTmpMap &props, const LinkBaseExtension::PropInfoMap &infoMap,
|
||||
const PropMap &propMap, PyObject *key, PyObject *value)
|
||||
static bool getProperty(PropTmpMap& props,
|
||||
const LinkBaseExtension::PropInfoMap& infoMap,
|
||||
const PropMap& propMap,
|
||||
PyObject* key,
|
||||
PyObject* value)
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
||||
if(!PyUnicode_Check(key)) {
|
||||
if (!PyUnicode_Check(key)) {
|
||||
PyErr_SetString(PyExc_TypeError, "key must be a unicode string");
|
||||
return false;
|
||||
}
|
||||
const char *keyStr = PyUnicode_AsUTF8(key);
|
||||
const char* keyStr = PyUnicode_AsUTF8(key);
|
||||
auto it = infoMap.find(keyStr);
|
||||
if(it == infoMap.end()){
|
||||
if (it == infoMap.end()) {
|
||||
str << "unknown key '" << keyStr << "'";
|
||||
PyErr_SetString(PyExc_KeyError, str.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *valStr = nullptr;
|
||||
if(key == value)
|
||||
const char* valStr = nullptr;
|
||||
if (key == value) {
|
||||
valStr = keyStr;
|
||||
else if (value!=Py_None) {
|
||||
if(!PyUnicode_Check(value)) {
|
||||
}
|
||||
else if (value != Py_None) {
|
||||
if (!PyUnicode_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be unicode string");
|
||||
return false;
|
||||
}
|
||||
valStr = PyUnicode_AsUTF8(value);
|
||||
}
|
||||
|
||||
App::Property *prop = nullptr;
|
||||
auto &info = it->second;
|
||||
if(valStr) {
|
||||
App::Property* prop = nullptr;
|
||||
auto& info = it->second;
|
||||
if (valStr) {
|
||||
auto pIt = propMap.find(valStr);
|
||||
if(pIt == propMap.end()) {
|
||||
if (pIt == propMap.end()) {
|
||||
str << "cannot find property '" << valStr << "'";
|
||||
PyErr_SetString(PyExc_ValueError, str.str().c_str());
|
||||
return false;
|
||||
}
|
||||
prop = pIt->second;
|
||||
if(!prop->isDerivedFrom(info.type)) {
|
||||
str << "expect property '" << keyStr << "(" << valStr
|
||||
<< ") to be derived from '" << info.type.getName()
|
||||
<< "', instead of '" << prop->getTypeId().getName() << "'";
|
||||
if (!prop->isDerivedFrom(info.type)) {
|
||||
str << "expect property '" << keyStr << "(" << valStr << ") to be derived from '"
|
||||
<< info.type.getName() << "', instead of '" << prop->getTypeId().getName() << "'";
|
||||
PyErr_SetString(PyExc_TypeError, str.str().c_str());
|
||||
}
|
||||
}
|
||||
props[keyStr] = std::make_pair(info.index,prop);
|
||||
props[keyStr] = std::make_pair(info.index, prop);
|
||||
return true;
|
||||
}
|
||||
|
||||
PyObject* LinkBaseExtensionPy::configLinkProperty(PyObject *args, PyObject *keywds) {
|
||||
PyObject* LinkBaseExtensionPy::configLinkProperty(PyObject* args, PyObject* keywds)
|
||||
{
|
||||
auto ext = getLinkBaseExtensionPtr();
|
||||
const auto &info = ext->getPropertyInfoMap();
|
||||
const auto& info = ext->getPropertyInfoMap();
|
||||
|
||||
PropMap propMap;
|
||||
ext->getExtendedContainer()->getPropertyMap(propMap);
|
||||
|
||||
PropTmpMap props;
|
||||
|
||||
if(args && PyTuple_Check(args)) {
|
||||
for(Py_ssize_t pos=0;pos<PyTuple_GET_SIZE(args);++pos) {
|
||||
auto key = PyTuple_GET_ITEM(args,pos);
|
||||
if(!getProperty(props,info,propMap,key,key))
|
||||
if (args && PyTuple_Check(args)) {
|
||||
for (Py_ssize_t pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) {
|
||||
auto key = PyTuple_GET_ITEM(args, pos);
|
||||
if (!getProperty(props, info, propMap, key, key)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(keywds && PyDict_Check(keywds)) {
|
||||
if (keywds && PyDict_Check(keywds)) {
|
||||
PyObject *key, *value;
|
||||
Py_ssize_t pos = 0;
|
||||
while (PyDict_Next(keywds, &pos, &key, &value)) {
|
||||
if(!getProperty(props,info,propMap,key,value))
|
||||
if (!getProperty(props, info, propMap, key, value)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(auto &v : props)
|
||||
ext->setProperty(v.second.first,v.second.second);
|
||||
for (auto& v : props) {
|
||||
ext->setProperty(v.second.first, v.second.second);
|
||||
}
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* LinkBaseExtensionPy::getLinkExtProperty(PyObject *args)
|
||||
PyObject* LinkBaseExtensionPy::getLinkExtProperty(PyObject* args)
|
||||
{
|
||||
const char *name;
|
||||
if(!PyArg_ParseTuple(args,"s",&name))
|
||||
const char* name;
|
||||
if (!PyArg_ParseTuple(args, "s", &name)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto prop = getLinkBaseExtensionPtr()->getProperty(name);
|
||||
if(!prop) {
|
||||
if (!prop) {
|
||||
PyErr_SetString(PyExc_AttributeError, "unknown property name");
|
||||
return nullptr;
|
||||
}
|
||||
return prop->getPyObject();
|
||||
}
|
||||
|
||||
PyObject* LinkBaseExtensionPy::getLinkExtPropertyName(PyObject *args) {
|
||||
const char *name;
|
||||
if(!PyArg_ParseTuple(args,"s",&name))
|
||||
PyObject* LinkBaseExtensionPy::getLinkExtPropertyName(PyObject* args)
|
||||
{
|
||||
const char* name;
|
||||
if (!PyArg_ParseTuple(args, "s", &name)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto prop = getLinkBaseExtensionPtr()->getProperty(name);
|
||||
if(!prop) {
|
||||
if (!prop) {
|
||||
PyErr_SetString(PyExc_AttributeError, "unknown property name");
|
||||
return nullptr;
|
||||
}
|
||||
auto container = getLinkBaseExtensionPtr()->getExtendedContainer();
|
||||
if(!container) {
|
||||
if (!container) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "no extended container");
|
||||
return nullptr;
|
||||
}
|
||||
name = container->getPropertyName(prop);
|
||||
if(!name) {
|
||||
if (!name) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "cannot find property name");
|
||||
return nullptr;
|
||||
}
|
||||
return Py::new_reference_to(Py::String(name));
|
||||
}
|
||||
|
||||
PyObject* LinkBaseExtensionPy::getLinkPropertyInfo(PyObject *args)
|
||||
PyObject* LinkBaseExtensionPy::getLinkPropertyInfo(PyObject* args)
|
||||
{
|
||||
auto ext = getLinkBaseExtensionPtr();
|
||||
|
||||
const auto &infos = ext->getPropertyInfo();
|
||||
const auto& infos = ext->getPropertyInfo();
|
||||
|
||||
if(PyArg_ParseTuple(args,"")) {
|
||||
if (PyArg_ParseTuple(args, "")) {
|
||||
Py::Tuple ret(infos.size());
|
||||
int i=0;
|
||||
for(const auto &info : infos) {
|
||||
ret.setItem(i++,Py::TupleN(Py::String(info.name),
|
||||
Py::String(info.type.getName()),Py::String(info.doc)));
|
||||
int i = 0;
|
||||
for (const auto& info : infos) {
|
||||
ret.setItem(i++,
|
||||
Py::TupleN(Py::String(info.name),
|
||||
Py::String(info.type.getName()),
|
||||
Py::String(info.doc)));
|
||||
}
|
||||
return Py::new_reference_to(ret);
|
||||
}
|
||||
|
||||
short index = 0;
|
||||
if(PyArg_ParseTuple(args,"h",&index)) {
|
||||
if(index<0 || index>=(int)infos.size()) {
|
||||
if (PyArg_ParseTuple(args, "h", &index)) {
|
||||
if (index < 0 || index >= (int)infos.size()) {
|
||||
PyErr_SetString(PyExc_ValueError, "index out of range");
|
||||
return nullptr;
|
||||
}
|
||||
Py::TupleN ret(Py::String(infos[index].name),
|
||||
Py::String(infos[index].type.getName()),Py::String(infos[index].doc));
|
||||
Py::String(infos[index].type.getName()),
|
||||
Py::String(infos[index].doc));
|
||||
return Py::new_reference_to(ret);
|
||||
}
|
||||
|
||||
char *name;
|
||||
if(PyArg_ParseTuple(args,"s",&name)) {
|
||||
for(const auto & info : infos) {
|
||||
if(strcmp(info.name,name)==0) {
|
||||
Py::TupleN ret(Py::String(info.type.getName()),
|
||||
Py::String(info.doc));
|
||||
char* name;
|
||||
if (PyArg_ParseTuple(args, "s", &name)) {
|
||||
for (const auto& info : infos) {
|
||||
if (strcmp(info.name, name) == 0) {
|
||||
Py::TupleN ret(Py::String(info.type.getName()), Py::String(info.doc));
|
||||
return Py::new_reference_to(ret);
|
||||
}
|
||||
}
|
||||
@@ -200,101 +212,128 @@ PyObject* LinkBaseExtensionPy::getLinkPropertyInfo(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void parseLink(LinkBaseExtension *ext, int index, PyObject *value) {
|
||||
App::DocumentObject *obj = nullptr;
|
||||
void parseLink(LinkBaseExtension* ext, int index, PyObject* value)
|
||||
{
|
||||
App::DocumentObject* obj = nullptr;
|
||||
PropertyStringList subs;
|
||||
PropertyString sub;
|
||||
if(value!=Py_None) {
|
||||
if(PyObject_TypeCheck(value,&DocumentObjectPy::Type)) {
|
||||
if (value != Py_None) {
|
||||
if (PyObject_TypeCheck(value, &DocumentObjectPy::Type)) {
|
||||
obj = static_cast<DocumentObjectPy*>(value)->getDocumentObjectPtr();
|
||||
}else if(!PySequence_Check(value))
|
||||
}
|
||||
else if (!PySequence_Check(value)) {
|
||||
throw Base::TypeError("Expects type of DocumentObject or sequence");
|
||||
else{
|
||||
}
|
||||
else {
|
||||
Py::Sequence seq(value);
|
||||
if(seq[0].ptr() != Py_None) {
|
||||
if(!PyObject_TypeCheck(seq[0].ptr(),&DocumentObjectPy::Type))
|
||||
throw Base::TypeError("Expects the first argument to be DocumentObject in sequence");
|
||||
if (seq[0].ptr() != Py_None) {
|
||||
if (!PyObject_TypeCheck(seq[0].ptr(), &DocumentObjectPy::Type)) {
|
||||
throw Base::TypeError(
|
||||
"Expects the first argument to be DocumentObject in sequence");
|
||||
}
|
||||
obj = static_cast<DocumentObjectPy*>(seq[0].ptr())->getDocumentObjectPtr();
|
||||
if(seq.size()>1) {
|
||||
if (seq.size() > 1) {
|
||||
sub.setPyObject(seq[1].ptr());
|
||||
if(seq.size()>2)
|
||||
if (seq.size() > 2) {
|
||||
subs.setPyObject(seq[2].ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ext->setLink(index,obj,sub.getValue(),subs.getValue());
|
||||
ext->setLink(index, obj, sub.getValue(), subs.getValue());
|
||||
}
|
||||
|
||||
PyObject* LinkBaseExtensionPy::setLink(PyObject *_args)
|
||||
PyObject* LinkBaseExtensionPy::setLink(PyObject* _args)
|
||||
{
|
||||
Py::Sequence args(_args);
|
||||
PY_TRY {
|
||||
PY_TRY
|
||||
{
|
||||
auto ext = getLinkBaseExtensionPtr();
|
||||
PyObject *pcObj = args.size()?args[0].ptr():Py_None;
|
||||
if(pcObj == Py_None) {
|
||||
ext->setLink(-1,nullptr);
|
||||
}else if(PyDict_Check(pcObj)) {
|
||||
PyObject* pcObj = args.size() ? args[0].ptr() : Py_None;
|
||||
if (pcObj == Py_None) {
|
||||
ext->setLink(-1, nullptr);
|
||||
}
|
||||
else if (PyDict_Check(pcObj)) {
|
||||
PyObject *key, *value;
|
||||
Py_ssize_t pos = 0;
|
||||
while(PyDict_Next(pcObj, &pos, &key, &value))
|
||||
parseLink(ext,Py::Int(key),value);
|
||||
}else if(PySequence_Check(pcObj)) {
|
||||
ext->setLink(-1,nullptr);
|
||||
while (PyDict_Next(pcObj, &pos, &key, &value)) {
|
||||
parseLink(ext, Py::Int(key), value);
|
||||
}
|
||||
}
|
||||
else if (PySequence_Check(pcObj)) {
|
||||
ext->setLink(-1, nullptr);
|
||||
Py::Sequence seq(pcObj);
|
||||
for(Py_ssize_t i=0;i<seq.size();++i)
|
||||
parseLink(ext,i,seq[i].ptr());
|
||||
}else
|
||||
parseLink(ext,-1,_args);
|
||||
for (Py_ssize_t i = 0; i < seq.size(); ++i) {
|
||||
parseLink(ext, i, seq[i].ptr());
|
||||
}
|
||||
}
|
||||
else {
|
||||
parseLink(ext, -1, _args);
|
||||
}
|
||||
|
||||
Py_Return;
|
||||
}PY_CATCH
|
||||
}
|
||||
PY_CATCH
|
||||
}
|
||||
|
||||
PyObject* LinkBaseExtensionPy::cacheChildLabel(PyObject *args) {
|
||||
PyObject *enable = Py_True;
|
||||
if(!PyArg_ParseTuple(args,"|O",&enable))
|
||||
PyObject* LinkBaseExtensionPy::cacheChildLabel(PyObject* args)
|
||||
{
|
||||
PyObject* enable = Py_True;
|
||||
if (!PyArg_ParseTuple(args, "|O", &enable)) {
|
||||
return nullptr;
|
||||
PY_TRY {
|
||||
}
|
||||
PY_TRY
|
||||
{
|
||||
getLinkBaseExtensionPtr()->cacheChildLabel(Base::asBoolean(enable) ? -1 : 0);
|
||||
Py_Return;
|
||||
}PY_CATCH;
|
||||
}
|
||||
PY_CATCH;
|
||||
}
|
||||
|
||||
PyObject* LinkBaseExtensionPy::flattenSubname(PyObject *args) {
|
||||
const char *subname;
|
||||
if(!PyArg_ParseTuple(args,"s",&subname))
|
||||
PyObject* LinkBaseExtensionPy::flattenSubname(PyObject* args)
|
||||
{
|
||||
const char* subname;
|
||||
if (!PyArg_ParseTuple(args, "s", &subname)) {
|
||||
return nullptr;
|
||||
PY_TRY {
|
||||
return Py::new_reference_to(Py::String(
|
||||
getLinkBaseExtensionPtr()->flattenSubname(subname)));
|
||||
}PY_CATCH;
|
||||
}
|
||||
PY_TRY
|
||||
{
|
||||
return Py::new_reference_to(Py::String(getLinkBaseExtensionPtr()->flattenSubname(subname)));
|
||||
}
|
||||
PY_CATCH;
|
||||
}
|
||||
|
||||
PyObject* LinkBaseExtensionPy::expandSubname(PyObject *args) {
|
||||
const char *subname;
|
||||
if(!PyArg_ParseTuple(args,"s",&subname))
|
||||
PyObject* LinkBaseExtensionPy::expandSubname(PyObject* args)
|
||||
{
|
||||
const char* subname;
|
||||
if (!PyArg_ParseTuple(args, "s", &subname)) {
|
||||
return nullptr;
|
||||
PY_TRY {
|
||||
}
|
||||
PY_TRY
|
||||
{
|
||||
std::string sub(subname);
|
||||
getLinkBaseExtensionPtr()->expandSubname(sub);
|
||||
return Py::new_reference_to(Py::String(sub));
|
||||
}PY_CATCH;
|
||||
}
|
||||
PY_CATCH;
|
||||
}
|
||||
|
||||
Py::List LinkBaseExtensionPy::getLinkedChildren() const {
|
||||
Py::List LinkBaseExtensionPy::getLinkedChildren() const
|
||||
{
|
||||
Py::List ret;
|
||||
for(auto o : getLinkBaseExtensionPtr()->getLinkedChildren(true))
|
||||
for (auto o : getLinkBaseExtensionPtr()->getLinkedChildren(true)) {
|
||||
ret.append(Py::asObject(o->getPyObject()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
PyObject *LinkBaseExtensionPy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* LinkBaseExtensionPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int LinkBaseExtensionPy::setCustomAttributes(const char* /*attr*/, PyObject * /*obj*/)
|
||||
int LinkBaseExtensionPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
+15
-9
@@ -4,27 +4,33 @@ from os import sys, path
|
||||
# Actual code generation is done in Base/param_utils.py.
|
||||
|
||||
# The following code is to import param_util.py without needing __init__.py in Base directory
|
||||
sys.path.append(path.join(path.dirname(path.dirname(path.abspath(__file__))), 'Base'))
|
||||
sys.path.append(path.join(path.dirname(path.dirname(path.abspath(__file__))), "Base"))
|
||||
import params_utils
|
||||
|
||||
from params_utils import ParamBool, ParamInt, ParamString, ParamUInt, ParamFloat
|
||||
|
||||
NameSpace = 'App'
|
||||
ClassName = 'LinkParams'
|
||||
ParamPath = 'User parameter:BaseApp/Preferences/Link'
|
||||
ClassDoc = 'Convenient class to obtain App::Link related parameters'
|
||||
HeaderFile = 'Link.h'
|
||||
SourceFile = 'Link.cpp'
|
||||
NameSpace = "App"
|
||||
ClassName = "LinkParams"
|
||||
ParamPath = "User parameter:BaseApp/Preferences/Link"
|
||||
ClassDoc = "Convenient class to obtain App::Link related parameters"
|
||||
HeaderFile = "Link.h"
|
||||
SourceFile = "Link.cpp"
|
||||
|
||||
Params = [
|
||||
ParamBool('CopyOnChangeApplyToAll', True, '''\
|
||||
ParamBool(
|
||||
"CopyOnChangeApplyToAll",
|
||||
True,
|
||||
"""\
|
||||
Stores the last user choice of whether to apply CopyOnChange setup to all link
|
||||
that links to the same configurable object'''),
|
||||
that links to the same configurable object""",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def declare():
|
||||
params_utils.declare_begin(sys.modules[__name__], header=False)
|
||||
params_utils.declare_end(sys.modules[__name__])
|
||||
|
||||
|
||||
def define():
|
||||
params_utils.define(sys.modules[__name__], header=False)
|
||||
|
||||
+7
-7
@@ -150,17 +150,17 @@ struct AppExport Dependency
|
||||
explicit Dependency(std::string pkg);
|
||||
explicit Dependency(const XERCES_CPP_NAMESPACE::DOMElement* elem);
|
||||
std::string package; //< Required: must exactly match the contents of the "name" element in the
|
||||
//referenced package's package.xml file.
|
||||
// referenced package's package.xml file.
|
||||
std::string version_lt; //< Optional: The dependency to the package is restricted to versions
|
||||
//less than the stated version number.
|
||||
// less than the stated version number.
|
||||
std::string version_lte; //< Optional: The dependency to the package is restricted to versions
|
||||
//less or equal than the stated version number.
|
||||
// less or equal than the stated version number.
|
||||
std::string version_eq; //< Optional: The dependency to the package is restricted to a version
|
||||
//equal than the stated version number.
|
||||
// equal than the stated version number.
|
||||
std::string version_gte; //< Optional: The dependency to the package is restricted to versions
|
||||
//greater or equal than the stated version number.
|
||||
// greater or equal than the stated version number.
|
||||
std::string version_gt; //< Optional: The dependency to the package is restricted to versions
|
||||
//greater than the stated version number.
|
||||
// greater than the stated version number.
|
||||
std::string condition; //< Optional: Conditional expression as documented in REP149.
|
||||
bool optional; //< Optional: Whether this dependency is considered "optional"
|
||||
DependencyType dependencyType; //< Optional: defaults to "automatic"
|
||||
@@ -238,7 +238,7 @@ public:
|
||||
std::vector<Meta::License>
|
||||
license() const; //< Must be at least one, and most licenses require including a license file.
|
||||
std::vector<Meta::Url> url() const; //< Any number of URLs may be specified, but at least one
|
||||
//repository URL must be included at the package level.
|
||||
// repository URL must be included at the package level.
|
||||
std::vector<Meta::Contact>
|
||||
author() const; //< Any number of authors may be specified, and email addresses are optional.
|
||||
std::vector<Meta::Dependency>
|
||||
|
||||
+925
-701
File diff suppressed because it is too large
Load Diff
+296
-180
@@ -34,7 +34,8 @@
|
||||
|
||||
#include "ElementNamingUtils.h"
|
||||
|
||||
namespace Py {
|
||||
namespace Py
|
||||
{
|
||||
class Object;
|
||||
}
|
||||
namespace App
|
||||
@@ -43,12 +44,14 @@ namespace App
|
||||
using any = boost::any;
|
||||
|
||||
template<class T>
|
||||
inline const T &any_cast(const boost::any &value) {
|
||||
inline const T& any_cast(const boost::any& value)
|
||||
{
|
||||
return boost::any_cast<const T&>(value);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T &any_cast(boost::any &value) {
|
||||
inline T& any_cast(boost::any& value)
|
||||
{
|
||||
return boost::any_cast<T&>(value);
|
||||
}
|
||||
|
||||
@@ -58,48 +61,49 @@ class PropertyContainer;
|
||||
class DocumentObject;
|
||||
class ExpressionVisitor;
|
||||
|
||||
AppExport std::string quote(const std::string &input, bool toPython=false);
|
||||
AppExport std::string quote(const std::string& input, bool toPython = false);
|
||||
|
||||
// Unfortunately VS2013 does not support default move constructor, so we have
|
||||
// to implement them manually
|
||||
#define FC_DEFAULT_CTORS(_t) \
|
||||
_t(const _t &) = default;\
|
||||
_t &operator=(const _t &) = default;\
|
||||
_t(_t &&other) { *this = std::move(other); }\
|
||||
_t &operator=(_t &&other)
|
||||
#define FC_DEFAULT_CTORS(_t) \
|
||||
_t(const _t&) = default; \
|
||||
_t& operator=(const _t&) = default; \
|
||||
_t(_t&& other) \
|
||||
{ \
|
||||
*this = std::move(other); \
|
||||
} \
|
||||
_t& operator=(_t&& other)
|
||||
|
||||
class AppExport ObjectIdentifier {
|
||||
class AppExport ObjectIdentifier
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
class AppExport DocumentMapper {
|
||||
class AppExport DocumentMapper
|
||||
{
|
||||
public:
|
||||
explicit DocumentMapper(const std::map<std::string,std::string> &);
|
||||
explicit DocumentMapper(const std::map<std::string, std::string>&);
|
||||
~DocumentMapper();
|
||||
};
|
||||
|
||||
class String {
|
||||
class String
|
||||
{
|
||||
friend class ObjectIdentifier;
|
||||
|
||||
public:
|
||||
String(const std::string& s = "", bool _isRealString = false, bool _forceIdentifier = false)
|
||||
: str(s)
|
||||
, isString(_isRealString)
|
||||
, forceIdentifier(_forceIdentifier)
|
||||
{} // explicit bombs
|
||||
|
||||
String(const std::string &s = "",
|
||||
bool _isRealString = false,
|
||||
bool _forceIdentifier = false)
|
||||
: str(s),
|
||||
isString(_isRealString),
|
||||
forceIdentifier(_forceIdentifier)
|
||||
{}//explicit bombs
|
||||
|
||||
explicit String(std::string &&s,
|
||||
bool _isRealString = false,
|
||||
bool _forceIdentifier = false)
|
||||
: str(std::move(s)),
|
||||
isString(_isRealString),
|
||||
forceIdentifier(_forceIdentifier)
|
||||
explicit String(std::string&& s, bool _isRealString = false, bool _forceIdentifier = false)
|
||||
: str(std::move(s))
|
||||
, isString(_isRealString)
|
||||
, forceIdentifier(_forceIdentifier)
|
||||
{}
|
||||
|
||||
FC_DEFAULT_CTORS(String) {
|
||||
FC_DEFAULT_CTORS(String)
|
||||
{
|
||||
str = std::move(other.str);
|
||||
isString = other.isString;
|
||||
forceIdentifier = other.forceIdentifier;
|
||||
@@ -109,40 +113,70 @@ public:
|
||||
// Accessors
|
||||
|
||||
/** Returns the string */
|
||||
const std::string &getString() const { return str; }
|
||||
const std::string& getString() const
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
/** Return true is string need to be quoted */
|
||||
bool isRealString() const { return isString; }
|
||||
bool isRealString() const
|
||||
{
|
||||
return isString;
|
||||
}
|
||||
|
||||
bool isForceIdentifier() const { return forceIdentifier; }
|
||||
bool isForceIdentifier() const
|
||||
{
|
||||
return forceIdentifier;
|
||||
}
|
||||
|
||||
/** Returns a possibly quoted string */
|
||||
std::string toString(bool toPython=false) const;
|
||||
std::string toString(bool toPython = false) const;
|
||||
|
||||
// Operators
|
||||
|
||||
explicit operator std::string() const { return str; }
|
||||
explicit operator std::string() const
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
explicit operator const char *() const { return str.c_str(); }
|
||||
explicit operator const char*() const
|
||||
{
|
||||
return str.c_str();
|
||||
}
|
||||
|
||||
bool operator==(const String & other) const { return str == other.str; }
|
||||
bool operator==(const String& other) const
|
||||
{
|
||||
return str == other.str;
|
||||
}
|
||||
|
||||
bool operator!=(const String & other) const { return str != other.str; }
|
||||
bool operator!=(const String& other) const
|
||||
{
|
||||
return str != other.str;
|
||||
}
|
||||
|
||||
bool operator>=(const String & other) const { return str >= other.str; }
|
||||
bool operator>=(const String& other) const
|
||||
{
|
||||
return str >= other.str;
|
||||
}
|
||||
|
||||
bool operator<(const String & other) const { return str < other.str; }
|
||||
bool operator<(const String& other) const
|
||||
{
|
||||
return str < other.str;
|
||||
}
|
||||
|
||||
bool operator>(const String & other) const { return str > other.str; }
|
||||
bool operator>(const String& other) const
|
||||
{
|
||||
return str > other.str;
|
||||
}
|
||||
|
||||
void checkImport(const App::DocumentObject* owner,
|
||||
const App::DocumentObject* obj = nullptr,
|
||||
String* objName = nullptr);
|
||||
|
||||
void checkImport(const App::DocumentObject *owner,
|
||||
const App::DocumentObject *obj=nullptr, String *objName=nullptr);
|
||||
private:
|
||||
|
||||
std::string str;
|
||||
bool isString;
|
||||
bool forceIdentifier;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -151,21 +185,22 @@ public:
|
||||
* a single entry, and array, or a map to other sub-fields.
|
||||
*/
|
||||
|
||||
class AppExport Component {
|
||||
class AppExport Component
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
enum typeEnum {
|
||||
enum typeEnum
|
||||
{
|
||||
SIMPLE,
|
||||
MAP,
|
||||
ARRAY,
|
||||
RANGE,
|
||||
} ;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
FC_DEFAULT_CTORS(Component) {
|
||||
FC_DEFAULT_CTORS(Component)
|
||||
{
|
||||
name = std::move(other.name);
|
||||
type = other.type;
|
||||
begin = other.begin;
|
||||
@@ -174,98 +209,147 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
Component(const String &_name = String(), typeEnum _type=SIMPLE,
|
||||
int begin=INT_MAX, int end=INT_MAX, int step=1);//explicit bombs
|
||||
Component(String &&_name, typeEnum _type=SIMPLE,
|
||||
int begin=INT_MAX, int end=INT_MAX, int step=1);//explicit bombs
|
||||
Component(const String& _name = String(),
|
||||
typeEnum _type = SIMPLE,
|
||||
int begin = INT_MAX,
|
||||
int end = INT_MAX,
|
||||
int step = 1); // explicit bombs
|
||||
Component(String&& _name,
|
||||
typeEnum _type = SIMPLE,
|
||||
int begin = INT_MAX,
|
||||
int end = INT_MAX,
|
||||
int step = 1); // explicit bombs
|
||||
|
||||
static Component SimpleComponent(const char * _component);
|
||||
static Component SimpleComponent(const char* _component);
|
||||
|
||||
static Component SimpleComponent(const String & _component);
|
||||
static Component SimpleComponent(String &&_component);
|
||||
static Component SimpleComponent(const String& _component);
|
||||
static Component SimpleComponent(String&& _component);
|
||||
|
||||
static Component ArrayComponent(int _index);
|
||||
|
||||
static Component RangeComponent(int _begin, int _end = INT_MAX, int _step=1);
|
||||
static Component RangeComponent(int _begin, int _end = INT_MAX, int _step = 1);
|
||||
|
||||
static Component MapComponent(const String &_key);
|
||||
static Component MapComponent(String &&_key);
|
||||
static Component MapComponent(const String& _key);
|
||||
static Component MapComponent(String&& _key);
|
||||
|
||||
// Type queries
|
||||
|
||||
bool isSimple() const { return type == SIMPLE; }
|
||||
bool isSimple() const
|
||||
{
|
||||
return type == SIMPLE;
|
||||
}
|
||||
|
||||
bool isMap() const { return type == MAP; }
|
||||
bool isMap() const
|
||||
{
|
||||
return type == MAP;
|
||||
}
|
||||
|
||||
bool isArray() const { return type == ARRAY; }
|
||||
bool isArray() const
|
||||
{
|
||||
return type == ARRAY;
|
||||
}
|
||||
|
||||
bool isRange() const { return type == RANGE; }
|
||||
bool isRange() const
|
||||
{
|
||||
return type == RANGE;
|
||||
}
|
||||
|
||||
// Accessors
|
||||
|
||||
void toString(std::ostream &ss, bool toPython=false) const;
|
||||
void toString(std::ostream& ss, bool toPython = false) const;
|
||||
|
||||
const std::string &getName() const { return name.getString(); }
|
||||
const std::string& getName() const
|
||||
{
|
||||
return name.getString();
|
||||
}
|
||||
|
||||
int getIndex() const {return begin;}
|
||||
int getIndex() const
|
||||
{
|
||||
return begin;
|
||||
}
|
||||
size_t getIndex(size_t count) const;
|
||||
|
||||
int getBegin() const { return begin; }
|
||||
int getEnd() const { return end; }
|
||||
int getStep() const { return step; }
|
||||
int getBegin() const
|
||||
{
|
||||
return begin;
|
||||
}
|
||||
int getEnd() const
|
||||
{
|
||||
return end;
|
||||
}
|
||||
int getStep() const
|
||||
{
|
||||
return step;
|
||||
}
|
||||
|
||||
// Operators
|
||||
|
||||
bool operator==(const Component & other) const;
|
||||
bool operator<(const Component & other) const;
|
||||
bool operator==(const Component& other) const;
|
||||
bool operator<(const Component& other) const;
|
||||
|
||||
Py::Object get(const Py::Object &pyobj) const;
|
||||
void set(Py::Object &pyobj, const Py::Object &value) const;
|
||||
void del(Py::Object &pyobj) const;
|
||||
Py::Object get(const Py::Object& pyobj) const;
|
||||
void set(Py::Object& pyobj, const Py::Object& value) const;
|
||||
void del(Py::Object& pyobj) const;
|
||||
|
||||
private:
|
||||
|
||||
String name;
|
||||
typeEnum type;
|
||||
int begin;
|
||||
int end;
|
||||
int step;
|
||||
friend class ObjectIdentifier;
|
||||
|
||||
};
|
||||
|
||||
static Component SimpleComponent(const char * _component)
|
||||
{return Component::SimpleComponent(_component);}
|
||||
static Component SimpleComponent(const char* _component)
|
||||
{
|
||||
return Component::SimpleComponent(_component);
|
||||
}
|
||||
|
||||
static Component SimpleComponent(const String & _component)
|
||||
{return Component::SimpleComponent(_component);}
|
||||
static Component SimpleComponent(const String& _component)
|
||||
{
|
||||
return Component::SimpleComponent(_component);
|
||||
}
|
||||
|
||||
static Component SimpleComponent(String &&_component)
|
||||
{return Component::SimpleComponent(std::move(_component));}
|
||||
static Component SimpleComponent(String&& _component)
|
||||
{
|
||||
return Component::SimpleComponent(std::move(_component));
|
||||
}
|
||||
|
||||
static Component SimpleComponent(const std::string _component)
|
||||
{return Component::SimpleComponent(_component.c_str());}
|
||||
static Component SimpleComponent(const std::string _component)
|
||||
{
|
||||
return Component::SimpleComponent(_component.c_str());
|
||||
}
|
||||
|
||||
static Component ArrayComponent(int _index)
|
||||
{return Component::ArrayComponent(_index); }
|
||||
{
|
||||
return Component::ArrayComponent(_index);
|
||||
}
|
||||
|
||||
static Component RangeComponent(int _begin, int _end = INT_MAX, int _step=1)
|
||||
{return Component::RangeComponent(_begin,_end,_step);}
|
||||
static Component RangeComponent(int _begin, int _end = INT_MAX, int _step = 1)
|
||||
{
|
||||
return Component::RangeComponent(_begin, _end, _step);
|
||||
}
|
||||
|
||||
static Component MapComponent(const String &_key)
|
||||
{return Component::MapComponent(_key);}
|
||||
static Component MapComponent(const String& _key)
|
||||
{
|
||||
return Component::MapComponent(_key);
|
||||
}
|
||||
|
||||
static Component MapComponent(String &&_key)
|
||||
{return Component::MapComponent(_key);}
|
||||
static Component MapComponent(String&& _key)
|
||||
{
|
||||
return Component::MapComponent(_key);
|
||||
}
|
||||
|
||||
explicit ObjectIdentifier(const App::PropertyContainer * _owner = nullptr,
|
||||
const std::string & property = std::string(), int index=INT_MAX);
|
||||
explicit ObjectIdentifier(const App::PropertyContainer* _owner = nullptr,
|
||||
const std::string& property = std::string(),
|
||||
int index = INT_MAX);
|
||||
|
||||
ObjectIdentifier(const App::PropertyContainer * _owner, bool localProperty);
|
||||
ObjectIdentifier(const App::PropertyContainer* _owner, bool localProperty);
|
||||
|
||||
ObjectIdentifier(const App::Property & prop, int index=INT_MAX);//explicit bombs
|
||||
ObjectIdentifier(const App::Property& prop, int index = INT_MAX); // explicit bombs
|
||||
|
||||
FC_DEFAULT_CTORS(ObjectIdentifier) {
|
||||
FC_DEFAULT_CTORS(ObjectIdentifier)
|
||||
{
|
||||
owner = other.owner;
|
||||
documentName = std::move(other.documentName);
|
||||
documentObjectName = std::move(other.documentObjectName);
|
||||
@@ -282,16 +366,21 @@ public:
|
||||
|
||||
virtual ~ObjectIdentifier() = default;
|
||||
|
||||
App::DocumentObject *getOwner() const { return owner; }
|
||||
App::DocumentObject* getOwner() const
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
|
||||
// Components
|
||||
void addComponent(const Component &c) {
|
||||
void addComponent(const Component& c)
|
||||
{
|
||||
components.push_back(c);
|
||||
_cache.clear();
|
||||
}
|
||||
|
||||
// Components
|
||||
void addComponent(Component &&c) {
|
||||
void addComponent(Component&& c)
|
||||
{
|
||||
components.push_back(std::move(c));
|
||||
_cache.clear();
|
||||
}
|
||||
@@ -299,23 +388,29 @@ public:
|
||||
std::string getPropertyName() const;
|
||||
|
||||
template<typename C>
|
||||
void addComponents(const C &cs) { components.insert(components.end(), cs.begin(), cs.end()); }
|
||||
void addComponents(const C& cs)
|
||||
{
|
||||
components.insert(components.end(), cs.begin(), cs.end());
|
||||
}
|
||||
|
||||
const Component & getPropertyComponent(int i, int *idx=nullptr) const;
|
||||
const Component& getPropertyComponent(int i, int* idx = nullptr) const;
|
||||
|
||||
void setComponent(int idx, Component &&comp);
|
||||
void setComponent(int idx, const Component &comp);
|
||||
void setComponent(int idx, Component&& comp);
|
||||
void setComponent(int idx, const Component& comp);
|
||||
|
||||
std::vector<Component> getPropertyComponents() const;
|
||||
const std::vector<Component> &getComponents() const { return components; }
|
||||
const std::vector<Component>& getComponents() const
|
||||
{
|
||||
return components;
|
||||
}
|
||||
|
||||
std::string getSubPathStr(bool toPython=false) const;
|
||||
std::string getSubPathStr(bool toPython = false) const;
|
||||
|
||||
int numComponents() const;
|
||||
|
||||
int numSubComponents() const;
|
||||
|
||||
const std::string &toString() const;
|
||||
const std::string& toString() const;
|
||||
|
||||
std::string toPersistentString() const;
|
||||
|
||||
@@ -323,37 +418,46 @@ public:
|
||||
|
||||
bool isTouched() const;
|
||||
|
||||
App::Property *getProperty(int *ptype=nullptr) const;
|
||||
App::Property* getProperty(int* ptype = nullptr) const;
|
||||
|
||||
App::ObjectIdentifier canonicalPath() const;
|
||||
|
||||
// Document-centric functions
|
||||
|
||||
void setDocumentName(String &&name, bool force = false);
|
||||
void setDocumentName(String&& name, bool force = false);
|
||||
|
||||
String getDocumentName() const;
|
||||
|
||||
void setDocumentObjectName(String &&name, bool force = false,
|
||||
String &&subname = String(), bool checkImport=false);
|
||||
void setDocumentObjectName(String&& name,
|
||||
bool force = false,
|
||||
String&& subname = String(),
|
||||
bool checkImport = false);
|
||||
|
||||
void setDocumentObjectName(const App::DocumentObject *obj, bool force = false,
|
||||
String &&subname = String(), bool checkImport=false);
|
||||
void setDocumentObjectName(const App::DocumentObject* obj,
|
||||
bool force = false,
|
||||
String&& subname = String(),
|
||||
bool checkImport = false);
|
||||
|
||||
bool hasDocumentObjectName(bool forced=false) const;
|
||||
bool hasDocumentObjectName(bool forced = false) const;
|
||||
|
||||
bool isLocalProperty() const { return localProperty; }
|
||||
bool isLocalProperty() const
|
||||
{
|
||||
return localProperty;
|
||||
}
|
||||
|
||||
String getDocumentObjectName() const;
|
||||
|
||||
const std::string &getSubObjectName(bool newStyle) const;
|
||||
const std::string &getSubObjectName() const;
|
||||
const std::string& getSubObjectName(bool newStyle) const;
|
||||
const std::string& getSubObjectName() const;
|
||||
|
||||
using SubNameMap = std::map<std::pair<App::DocumentObject*,std::string>,std::string>;
|
||||
void importSubNames(const SubNameMap &subNameMap);
|
||||
using SubNameMap = std::map<std::pair<App::DocumentObject*, std::string>, std::string>;
|
||||
void importSubNames(const SubNameMap& subNameMap);
|
||||
|
||||
bool updateLabelReference(App::DocumentObject *, const std::string &, const char *);
|
||||
bool updateLabelReference(App::DocumentObject*, const std::string&, const char*);
|
||||
|
||||
bool relabeledDocument(ExpressionVisitor &v, const std::string &oldLabel, const std::string &newLabel);
|
||||
bool relabeledDocument(ExpressionVisitor& v,
|
||||
const std::string& oldLabel,
|
||||
const std::string& newLabel);
|
||||
|
||||
/** Type for storing dependency of an ObjectIdentifier
|
||||
*
|
||||
@@ -365,7 +469,7 @@ public:
|
||||
* the property may not exist at the time this ObjectIdentifier is
|
||||
* constructed.
|
||||
*/
|
||||
using Dependencies = std::map<App::DocumentObject *, std::set<std::string> >;
|
||||
using Dependencies = std::map<App::DocumentObject*, std::set<std::string>>;
|
||||
|
||||
/** Get dependencies of this object identifier
|
||||
*
|
||||
@@ -377,7 +481,7 @@ public:
|
||||
* first referred object dependency. Or else, all object and property
|
||||
* dependencies will be returned.
|
||||
*/
|
||||
Dependencies getDep(bool needProps, std::vector<std::string> *labels=nullptr) const;
|
||||
Dependencies getDep(bool needProps, std::vector<std::string>* labels = nullptr) const;
|
||||
|
||||
/** Get dependencies of this object identifier
|
||||
*
|
||||
@@ -390,104 +494,112 @@ public:
|
||||
* first referred object dependency. Or else, all object and property
|
||||
* dependencies will be returned.
|
||||
*/
|
||||
void getDep(Dependencies &deps, bool needProps, std::vector<std::string> *labels=nullptr) const;
|
||||
void
|
||||
getDep(Dependencies& deps, bool needProps, std::vector<std::string>* labels = nullptr) const;
|
||||
|
||||
/// Returns all label references
|
||||
void getDepLabels(std::vector<std::string> &labels) const;
|
||||
void getDepLabels(std::vector<std::string>& labels) const;
|
||||
|
||||
App::Document *getDocument(String name = String(), bool *ambiguous=nullptr) const;
|
||||
App::Document* getDocument(String name = String(), bool* ambiguous = nullptr) const;
|
||||
|
||||
App::DocumentObject *getDocumentObject() const;
|
||||
App::DocumentObject* getDocumentObject() const;
|
||||
|
||||
std::vector<std::string> getStringList() const;
|
||||
|
||||
App::ObjectIdentifier relativeTo(const App::ObjectIdentifier & other) const;
|
||||
App::ObjectIdentifier relativeTo(const App::ObjectIdentifier& other) const;
|
||||
|
||||
bool replaceObject(ObjectIdentifier &res, const App::DocumentObject *parent,
|
||||
App::DocumentObject *oldObj, App::DocumentObject *newObj) const;
|
||||
bool replaceObject(ObjectIdentifier& res,
|
||||
const App::DocumentObject* parent,
|
||||
App::DocumentObject* oldObj,
|
||||
App::DocumentObject* newObj) const;
|
||||
|
||||
// Operators
|
||||
|
||||
App::ObjectIdentifier & operator<<(const Component & value);
|
||||
App::ObjectIdentifier & operator<<(Component &&value);
|
||||
App::ObjectIdentifier& operator<<(const Component& value);
|
||||
App::ObjectIdentifier& operator<<(Component&& value);
|
||||
|
||||
bool operator==(const ObjectIdentifier & other) const;
|
||||
bool operator==(const ObjectIdentifier& other) const;
|
||||
|
||||
bool operator!=(const ObjectIdentifier & other) const;
|
||||
bool operator!=(const ObjectIdentifier& other) const;
|
||||
|
||||
bool operator<(const ObjectIdentifier &other) const;
|
||||
bool operator<(const ObjectIdentifier& other) const;
|
||||
|
||||
// Getter
|
||||
|
||||
App::any getValue(bool pathValue=false, bool *isPseudoProperty=nullptr) const;
|
||||
App::any getValue(bool pathValue = false, bool* isPseudoProperty = nullptr) const;
|
||||
|
||||
Py::Object getPyValue(bool pathValue=false, bool *isPseudoProperty=nullptr) const;
|
||||
Py::Object getPyValue(bool pathValue = false, bool* isPseudoProperty = nullptr) const;
|
||||
|
||||
// Setter: is const because it does not alter the object state,
|
||||
// but does have an aiding effect.
|
||||
|
||||
void setValue(const App::any & value) const;
|
||||
void setValue(const App::any& value) const;
|
||||
|
||||
// Static functions
|
||||
|
||||
static ObjectIdentifier parse(const App::DocumentObject *docObj, const std::string & str);
|
||||
static ObjectIdentifier parse(const App::DocumentObject* docObj, const std::string& str);
|
||||
|
||||
std::string resolveErrorString() const;
|
||||
|
||||
bool adjustLinks(ExpressionVisitor &v, const std::set<App::DocumentObject *> &inList);
|
||||
bool adjustLinks(ExpressionVisitor& v, const std::set<App::DocumentObject*>& inList);
|
||||
|
||||
bool updateElementReference(ExpressionVisitor &v, App::DocumentObject *feature=nullptr, bool reverse=false);
|
||||
bool updateElementReference(ExpressionVisitor& v,
|
||||
App::DocumentObject* feature = nullptr,
|
||||
bool reverse = false);
|
||||
|
||||
void resolveAmbiguity();
|
||||
|
||||
bool verify(const App::Property &prop, bool silent=false) const;
|
||||
bool verify(const App::Property& prop, bool silent = false) const;
|
||||
|
||||
std::size_t hash() const;
|
||||
|
||||
protected:
|
||||
struct ResolveResults
|
||||
{
|
||||
|
||||
struct ResolveResults {
|
||||
explicit ResolveResults(const ObjectIdentifier& oi);
|
||||
|
||||
explicit ResolveResults(const ObjectIdentifier & oi);
|
||||
|
||||
int propertyIndex{0};
|
||||
App::Document * resolvedDocument{nullptr};
|
||||
int propertyIndex {0};
|
||||
App::Document* resolvedDocument {nullptr};
|
||||
String resolvedDocumentName;
|
||||
App::DocumentObject * resolvedDocumentObject{nullptr};
|
||||
App::DocumentObject* resolvedDocumentObject {nullptr};
|
||||
String resolvedDocumentObjectName;
|
||||
String subObjectName;
|
||||
App::DocumentObject * resolvedSubObject{nullptr};
|
||||
App::Property * resolvedProperty{nullptr};
|
||||
App::DocumentObject* resolvedSubObject {nullptr};
|
||||
App::Property* resolvedProperty {nullptr};
|
||||
std::string propertyName;
|
||||
int propertyType{0};
|
||||
int propertyType {0};
|
||||
std::bitset<32> flags;
|
||||
|
||||
std::string resolveErrorString() const;
|
||||
void getProperty(const ObjectIdentifier &oi);
|
||||
void getProperty(const ObjectIdentifier& oi);
|
||||
};
|
||||
|
||||
friend struct ResolveResults;
|
||||
|
||||
App::Property *resolveProperty(const App::DocumentObject *obj,
|
||||
const char *propertyName, App::DocumentObject *&sobj,int &ptype) const;
|
||||
App::Property* resolveProperty(const App::DocumentObject* obj,
|
||||
const char* propertyName,
|
||||
App::DocumentObject*& sobj,
|
||||
int& ptype) const;
|
||||
|
||||
void getSubPathStr(std::ostream &ss, const ResolveResults &result, bool toPython=false) const;
|
||||
void getSubPathStr(std::ostream& ss, const ResolveResults& result, bool toPython = false) const;
|
||||
|
||||
Py::Object access(const ResolveResults &rs,
|
||||
Py::Object *value=nullptr, Dependencies *deps=nullptr) const;
|
||||
Py::Object access(const ResolveResults& rs,
|
||||
Py::Object* value = nullptr,
|
||||
Dependencies* deps = nullptr) const;
|
||||
|
||||
void resolve(ResolveResults & results) const;
|
||||
void resolveAmbiguity(ResolveResults &results);
|
||||
void resolve(ResolveResults& results) const;
|
||||
void resolveAmbiguity(ResolveResults& results);
|
||||
|
||||
static App::DocumentObject *getDocumentObject(
|
||||
const App::Document *doc, const String &name, std::bitset<32> &flags);
|
||||
static App::DocumentObject*
|
||||
getDocumentObject(const App::Document* doc, const String& name, std::bitset<32>& flags);
|
||||
|
||||
void getDepLabels(const ResolveResults &result, std::vector<std::string> &labels) const;
|
||||
void getDepLabels(const ResolveResults& result, std::vector<std::string>& labels) const;
|
||||
|
||||
App::DocumentObject * owner;
|
||||
String documentName;
|
||||
String documentObjectName;
|
||||
String subObjectName;
|
||||
App::DocumentObject* owner;
|
||||
String documentName;
|
||||
String documentObjectName;
|
||||
String subObjectName;
|
||||
ElementNamePair shadowSub;
|
||||
std::vector<Component> components;
|
||||
bool documentNameSet;
|
||||
@@ -495,35 +607,39 @@ protected:
|
||||
bool localProperty;
|
||||
|
||||
private:
|
||||
std::string _cache; // Cached string represstation of this identifier
|
||||
std::size_t _hash; // Cached hash of this string
|
||||
std::string _cache; // Cached string represstation of this identifier
|
||||
std::size_t _hash; // Cached hash of this string
|
||||
};
|
||||
|
||||
inline std::size_t hash_value(const App::ObjectIdentifier & path) {
|
||||
inline std::size_t hash_value(const App::ObjectIdentifier& path)
|
||||
{
|
||||
return path.hash();
|
||||
}
|
||||
|
||||
/** Helper function to convert Python object to/from App::any
|
||||
*
|
||||
* WARNING! Must hold Python global interpreter lock before calling these
|
||||
* functions
|
||||
*/
|
||||
*
|
||||
* WARNING! Must hold Python global interpreter lock before calling these
|
||||
* functions
|
||||
*/
|
||||
//@{
|
||||
App::any AppExport pyObjectToAny(Py::Object pyobj, bool check=true);
|
||||
Py::Object AppExport pyObjectFromAny(const App::any &value);
|
||||
App::any AppExport pyObjectToAny(Py::Object pyobj, bool check = true);
|
||||
Py::Object AppExport pyObjectFromAny(const App::any& value);
|
||||
//@}
|
||||
}
|
||||
} // namespace App
|
||||
|
||||
namespace std {
|
||||
namespace std
|
||||
{
|
||||
|
||||
template<>
|
||||
struct hash<App::ObjectIdentifier> {
|
||||
struct hash<App::ObjectIdentifier>
|
||||
{
|
||||
using argument_type = App::ObjectIdentifier;
|
||||
using result_type = std::size_t;
|
||||
inline result_type operator()(argument_type const& s) const {
|
||||
inline result_type operator()(argument_type const& s) const
|
||||
{
|
||||
return s.hash();
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
||||
+100
-68
@@ -45,7 +45,7 @@ using namespace App;
|
||||
// Property
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
TYPESYSTEM_SOURCE_ABSTRACT(App::Property , Base::Persistence)
|
||||
TYPESYSTEM_SOURCE_ABSTRACT(App::Property, Base::Persistence)
|
||||
|
||||
//**************************************************************************
|
||||
// Construction/Destruction
|
||||
@@ -54,9 +54,8 @@ static std::atomic<int64_t> _PropID;
|
||||
|
||||
// Here is the implementation! Description should take place in the header file!
|
||||
Property::Property()
|
||||
: _id(++_PropID)
|
||||
{
|
||||
}
|
||||
: _id(++_PropID)
|
||||
{}
|
||||
|
||||
Property::~Property() = default;
|
||||
|
||||
@@ -75,16 +74,21 @@ bool Property::isValidName(const char* name)
|
||||
return name && name[0] != '\0';
|
||||
}
|
||||
|
||||
std::string Property::getFullName() const {
|
||||
std::string Property::getFullName() const
|
||||
{
|
||||
std::string name;
|
||||
if(myName) {
|
||||
if(father)
|
||||
if (myName) {
|
||||
if (father) {
|
||||
name = father->getFullName() + ".";
|
||||
else
|
||||
}
|
||||
else {
|
||||
name = "?.";
|
||||
}
|
||||
name += myName;
|
||||
}else
|
||||
}
|
||||
else {
|
||||
return "?";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -116,9 +120,11 @@ std::string Property::getFileName(const char* postfix, const char* prefix) const
|
||||
short Property::getType() const
|
||||
{
|
||||
short type = 0;
|
||||
#define GET_PTYPE(_name) do {\
|
||||
if(testStatus(App::Property::Prop##_name)) type|=Prop_##_name;\
|
||||
}while(0)
|
||||
#define GET_PTYPE(_name) \
|
||||
do { \
|
||||
if (testStatus(App::Property::Prop##_name)) \
|
||||
type |= Prop_##_name; \
|
||||
} while (0)
|
||||
GET_PTYPE(ReadOnly);
|
||||
GET_PTYPE(Hidden);
|
||||
GET_PTYPE(Output);
|
||||
@@ -128,10 +134,13 @@ short Property::getType() const
|
||||
return type;
|
||||
}
|
||||
|
||||
void Property::syncType(unsigned type) {
|
||||
#define SYNC_PTYPE(_name) do{\
|
||||
if(type & Prop_##_name) StatusBits.set((size_t)Prop##_name);\
|
||||
}while(0)
|
||||
void Property::syncType(unsigned type)
|
||||
{
|
||||
#define SYNC_PTYPE(_name) \
|
||||
do { \
|
||||
if (type & Prop_##_name) \
|
||||
StatusBits.set((size_t)Prop##_name); \
|
||||
} while (0)
|
||||
SYNC_PTYPE(ReadOnly);
|
||||
SYNC_PTYPE(Transient);
|
||||
SYNC_PTYPE(Hidden);
|
||||
@@ -150,32 +159,33 @@ const char* Property::getDocumentation() const
|
||||
return father->getPropertyDocumentation(this);
|
||||
}
|
||||
|
||||
void Property::setContainer(PropertyContainer *Father)
|
||||
void Property::setContainer(PropertyContainer* Father)
|
||||
{
|
||||
father = Father;
|
||||
}
|
||||
|
||||
void Property::setPathValue(const ObjectIdentifier &path, const boost::any &value)
|
||||
void Property::setPathValue(const ObjectIdentifier& path, const boost::any& value)
|
||||
{
|
||||
path.setValue(value);
|
||||
}
|
||||
|
||||
const boost::any Property::getPathValue(const ObjectIdentifier &path) const
|
||||
const boost::any Property::getPathValue(const ObjectIdentifier& path) const
|
||||
{
|
||||
return path.getValue();
|
||||
}
|
||||
|
||||
void Property::getPaths(std::vector<ObjectIdentifier> &paths) const
|
||||
void Property::getPaths(std::vector<ObjectIdentifier>& paths) const
|
||||
{
|
||||
paths.emplace_back(getContainer(), getName());
|
||||
}
|
||||
|
||||
ObjectIdentifier Property::canonicalPath(const ObjectIdentifier &p) const
|
||||
ObjectIdentifier Property::canonicalPath(const ObjectIdentifier& p) const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
namespace App {
|
||||
namespace App
|
||||
{
|
||||
/*!
|
||||
* \brief The PropertyCleaner struct
|
||||
* Make deleting dynamic property safer by postponing its destruction.
|
||||
@@ -186,43 +196,51 @@ namespace App {
|
||||
* removed property, and only deleting them when no onChanged() call is
|
||||
* active.
|
||||
*/
|
||||
struct PropertyCleaner {
|
||||
explicit PropertyCleaner(Property *p)
|
||||
struct PropertyCleaner
|
||||
{
|
||||
explicit PropertyCleaner(Property* p)
|
||||
: prop(p)
|
||||
{
|
||||
++_PropCleanerCounter;
|
||||
}
|
||||
~PropertyCleaner() {
|
||||
if(--_PropCleanerCounter)
|
||||
~PropertyCleaner()
|
||||
{
|
||||
if (--_PropCleanerCounter) {
|
||||
return;
|
||||
}
|
||||
bool found = false;
|
||||
while (!_RemovedProps.empty()) {
|
||||
auto p = _RemovedProps.back();
|
||||
_RemovedProps.pop_back();
|
||||
if(p != prop)
|
||||
if (p != prop) {
|
||||
delete p;
|
||||
else
|
||||
}
|
||||
else {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
if (found) {
|
||||
_RemovedProps.push_back(prop);
|
||||
}
|
||||
}
|
||||
static void add(Property *prop) {
|
||||
static void add(Property* prop)
|
||||
{
|
||||
_RemovedProps.push_back(prop);
|
||||
}
|
||||
|
||||
Property *prop;
|
||||
Property* prop;
|
||||
|
||||
static std::vector<Property*> _RemovedProps;
|
||||
static int _PropCleanerCounter;
|
||||
};
|
||||
}
|
||||
} // namespace App
|
||||
|
||||
std::vector<Property*> PropertyCleaner::_RemovedProps;
|
||||
int PropertyCleaner::_PropCleanerCounter = 0;
|
||||
|
||||
void Property::destroy(Property *p) {
|
||||
void Property::destroy(Property* p)
|
||||
{
|
||||
if (p) {
|
||||
// Is it necessary to nullify the container? May cause crash if any
|
||||
// onChanged() caller assumes a non-null container.
|
||||
@@ -253,8 +271,8 @@ void Property::hasSetValue()
|
||||
PropertyCleaner guard(this);
|
||||
if (father) {
|
||||
father->onChanged(this);
|
||||
if(!testStatus(Busy)) {
|
||||
Base::BitsetLocker<decltype(StatusBits)> guard(StatusBits,Busy);
|
||||
if (!testStatus(Busy)) {
|
||||
Base::BitsetLocker<decltype(StatusBits)> guard(StatusBits, Busy);
|
||||
signalChanged(*this);
|
||||
}
|
||||
}
|
||||
@@ -263,16 +281,17 @@ void Property::hasSetValue()
|
||||
|
||||
void Property::aboutToSetValue()
|
||||
{
|
||||
if (father)
|
||||
if (father) {
|
||||
father->onBeforeChange(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Property::verifyPath(const ObjectIdentifier &p) const
|
||||
void Property::verifyPath(const ObjectIdentifier& p) const
|
||||
{
|
||||
p.verify(*this);
|
||||
}
|
||||
|
||||
Property *Property::Copy() const
|
||||
Property* Property::Copy() const
|
||||
{
|
||||
// have to be reimplemented by a subclass!
|
||||
assert(0);
|
||||
@@ -285,7 +304,8 @@ void Property::Paste(const Property& /*from*/)
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void Property::setStatusValue(unsigned long status) {
|
||||
void Property::setStatusValue(unsigned long status)
|
||||
{
|
||||
// clang-format off
|
||||
static const unsigned long mask =
|
||||
(1<<PropDynamic)
|
||||
@@ -303,26 +323,31 @@ void Property::setStatusValue(unsigned long status) {
|
||||
unsigned long oldStatus = StatusBits.to_ulong();
|
||||
StatusBits = decltype(StatusBits)(status);
|
||||
|
||||
if(father) {
|
||||
static unsigned long _signalMask = (1<<ReadOnly) | (1<<Hidden);
|
||||
if((status & _signalMask) != (oldStatus & _signalMask))
|
||||
father->onPropertyStatusChanged(*this,oldStatus);
|
||||
if (father) {
|
||||
static unsigned long _signalMask = (1 << ReadOnly) | (1 << Hidden);
|
||||
if ((status & _signalMask) != (oldStatus & _signalMask)) {
|
||||
father->onPropertyStatusChanged(*this, oldStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Property::setStatus(Status pos, bool on) {
|
||||
void Property::setStatus(Status pos, bool on)
|
||||
{
|
||||
auto bits = StatusBits;
|
||||
bits.set(pos,on);
|
||||
bits.set(pos, on);
|
||||
setStatusValue(bits.to_ulong());
|
||||
}
|
||||
|
||||
bool Property::isSame(const Property &other) const {
|
||||
if(&other == this)
|
||||
bool Property::isSame(const Property& other) const
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
if(other.getTypeId() != getTypeId() || getMemSize() != other.getMemSize())
|
||||
}
|
||||
if (other.getTypeId() != getTypeId() || getMemSize() != other.getMemSize()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Base::StringWriter writer,writer2;
|
||||
Base::StringWriter writer, writer2;
|
||||
Save(writer);
|
||||
other.Save(writer2);
|
||||
return writer.getString() == writer2.getString();
|
||||
@@ -333,9 +358,10 @@ bool Property::isSame(const Property &other) const {
|
||||
// PropertyListsBase
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
void PropertyListsBase::_setPyObject(PyObject *value) {
|
||||
void PropertyListsBase::_setPyObject(PyObject* value)
|
||||
{
|
||||
std::vector<int> indices;
|
||||
std::vector<PyObject *> vals;
|
||||
std::vector<PyObject*> vals;
|
||||
Py::Object pySeq;
|
||||
|
||||
if (PyDict_Check(value)) {
|
||||
@@ -344,42 +370,48 @@ void PropertyListsBase::_setPyObject(PyObject *value) {
|
||||
vals.reserve(size);
|
||||
indices.reserve(size);
|
||||
int listSize = getSize();
|
||||
for(auto it=dict.begin();it!=dict.end();++it) {
|
||||
const auto &item = *it;
|
||||
PyObject *key = item.first.ptr();
|
||||
if(!PyLong_Check(key))
|
||||
for (auto it = dict.begin(); it != dict.end(); ++it) {
|
||||
const auto& item = *it;
|
||||
PyObject* key = item.first.ptr();
|
||||
if (!PyLong_Check(key)) {
|
||||
throw Base::TypeError("expect key type to be integer");
|
||||
}
|
||||
long idx = PyLong_AsLong(key);
|
||||
if(idx<-1 || idx>listSize)
|
||||
if (idx < -1 || idx > listSize) {
|
||||
throw Base::ValueError("index out of bound");
|
||||
if(idx==-1 || idx==listSize) {
|
||||
}
|
||||
if (idx == -1 || idx == listSize) {
|
||||
idx = listSize;
|
||||
++listSize;
|
||||
}
|
||||
indices.push_back(idx);
|
||||
vals.push_back(item.second.ptr());
|
||||
}
|
||||
} else {
|
||||
if (PySequence_Check(value))
|
||||
}
|
||||
else {
|
||||
if (PySequence_Check(value)) {
|
||||
pySeq = value;
|
||||
}
|
||||
else {
|
||||
PyObject *iter = PyObject_GetIter(value);
|
||||
if(iter) {
|
||||
Py::Object pyIter(iter,true);
|
||||
pySeq = Py::asObject(PySequence_Fast(iter,""));
|
||||
} else {
|
||||
PyObject* iter = PyObject_GetIter(value);
|
||||
if (iter) {
|
||||
Py::Object pyIter(iter, true);
|
||||
pySeq = Py::asObject(PySequence_Fast(iter, ""));
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
vals.push_back(value);
|
||||
}
|
||||
}
|
||||
if(!pySeq.isNone()) {
|
||||
if (!pySeq.isNone()) {
|
||||
Py::Sequence seq(pySeq);
|
||||
vals.reserve(seq.size());
|
||||
for(auto it=seq.begin();it!=seq.end();++it)
|
||||
for (auto it = seq.begin(); it != seq.end(); ++it) {
|
||||
vals.push_back((*it).ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
setPyValues(vals,indices);
|
||||
setPyValues(vals, indices);
|
||||
}
|
||||
|
||||
|
||||
@@ -388,4 +420,4 @@ void PropertyListsBase::_setPyObject(PyObject *value) {
|
||||
// PropertyLists
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
TYPESYSTEM_SOURCE_ABSTRACT(App::PropertyLists , App::Property)
|
||||
TYPESYSTEM_SOURCE_ABSTRACT(App::PropertyLists, App::Property)
|
||||
|
||||
+195
-122
@@ -33,7 +33,8 @@
|
||||
#include <FCGlobal.h>
|
||||
|
||||
#include "ElementNamingUtils.h"
|
||||
namespace Py {
|
||||
namespace Py
|
||||
{
|
||||
class Object;
|
||||
}
|
||||
|
||||
@@ -52,33 +53,34 @@ class ObjectIdentifier;
|
||||
* possible properties. It is also possible to define user properties
|
||||
* and use them in the framework...
|
||||
*/
|
||||
class AppExport Property : public Base::Persistence
|
||||
class AppExport Property: public Base::Persistence
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
enum Status
|
||||
{
|
||||
Touched = 0, // touched property
|
||||
Immutable = 1, // can't modify property
|
||||
ReadOnly = 2, // for property editor
|
||||
Hidden = 3, // for property editor
|
||||
Transient = 4, // for property container save
|
||||
MaterialEdit = 5, // to turn ON PropertyMaterial edit
|
||||
NoMaterialListEdit = 6, // to turn OFF PropertyMaterialList edit
|
||||
Output = 7, // same effect as Prop_Output
|
||||
LockDynamic = 8, // prevent being removed from dynamic property
|
||||
NoModify = 9, // prevent causing Gui::Document::setModified()
|
||||
PartialTrigger = 10, // allow change in partial doc
|
||||
NoRecompute = 11, // touch owner for recompute on property change
|
||||
Single = 12, // for save/load of floating point numbers
|
||||
Ordered = 13, // for PropertyLists whether the order of the elements is
|
||||
// relevant for the container using it
|
||||
EvalOnRestore = 14, // In case of expression binding, evaluate the
|
||||
// expression on restore and touch the object on value change.
|
||||
Busy = 15, // internal use to avoid recursive signaling
|
||||
CopyOnChange = 16, // for Link to copy the linked object on change of the property with this flag
|
||||
UserEdit = 17, // cause property editor to create button for user defined editing
|
||||
Touched = 0, // touched property
|
||||
Immutable = 1, // can't modify property
|
||||
ReadOnly = 2, // for property editor
|
||||
Hidden = 3, // for property editor
|
||||
Transient = 4, // for property container save
|
||||
MaterialEdit = 5, // to turn ON PropertyMaterial edit
|
||||
NoMaterialListEdit = 6, // to turn OFF PropertyMaterialList edit
|
||||
Output = 7, // same effect as Prop_Output
|
||||
LockDynamic = 8, // prevent being removed from dynamic property
|
||||
NoModify = 9, // prevent causing Gui::Document::setModified()
|
||||
PartialTrigger = 10, // allow change in partial doc
|
||||
NoRecompute = 11, // touch owner for recompute on property change
|
||||
Single = 12, // for save/load of floating point numbers
|
||||
Ordered = 13, // for PropertyLists whether the order of the elements is
|
||||
// relevant for the container using it
|
||||
EvalOnRestore = 14, // In case of expression binding, evaluate the
|
||||
// expression on restore and touch the object on value change.
|
||||
Busy = 15, // internal use to avoid recursive signaling
|
||||
CopyOnChange =
|
||||
16, // for Link to copy the linked object on change of the property with this flag
|
||||
UserEdit = 17, // cause property editor to create button for user defined editing
|
||||
|
||||
// The following bits are corresponding to PropertyType set when the
|
||||
// property added. These types are meant to be static, and cannot be
|
||||
@@ -86,26 +88,26 @@ public:
|
||||
// required in PropertyContainer::getPropertyType()
|
||||
//
|
||||
PropStaticBegin = 21,
|
||||
PropDynamic = 21, // indicating the property is dynamically added
|
||||
PropNoPersist = 22, // corresponding to Prop_NoPersist
|
||||
PropNoRecompute = 23, // corresponding to Prop_NoRecompute
|
||||
PropReadOnly = 24, // corresponding to Prop_ReadOnly
|
||||
PropTransient= 25, // corresponding to Prop_Transient
|
||||
PropHidden = 26, // corresponding to Prop_Hidden
|
||||
PropOutput = 27, // corresponding to Prop_Output
|
||||
PropDynamic = 21, // indicating the property is dynamically added
|
||||
PropNoPersist = 22, // corresponding to Prop_NoPersist
|
||||
PropNoRecompute = 23, // corresponding to Prop_NoRecompute
|
||||
PropReadOnly = 24, // corresponding to Prop_ReadOnly
|
||||
PropTransient = 25, // corresponding to Prop_Transient
|
||||
PropHidden = 26, // corresponding to Prop_Hidden
|
||||
PropOutput = 27, // corresponding to Prop_Output
|
||||
PropStaticEnd = 28,
|
||||
|
||||
User1 = 28, // user-defined status
|
||||
User2 = 29, // user-defined status
|
||||
User3 = 30, // user-defined status
|
||||
User4 = 31 // user-defined status
|
||||
User1 = 28, // user-defined status
|
||||
User2 = 29, // user-defined status
|
||||
User3 = 30, // user-defined status
|
||||
User4 = 31 // user-defined status
|
||||
};
|
||||
|
||||
Property();
|
||||
~Property() override;
|
||||
|
||||
/// For safe deleting of a dynamic property
|
||||
static void destroy(Property *p);
|
||||
static void destroy(Property* p);
|
||||
|
||||
/** This method is used to get the size of objects
|
||||
* It is not meant to have the exact size, it is more or less an estimation
|
||||
@@ -113,7 +115,8 @@ public:
|
||||
* This method is defined in Base::Persistence
|
||||
* @see Base::Persistence
|
||||
*/
|
||||
unsigned int getMemSize () const override {
|
||||
unsigned int getMemSize() const override
|
||||
{
|
||||
// you have to implement this method in all property classes!
|
||||
return sizeof(father) + sizeof(StatusBits);
|
||||
}
|
||||
@@ -136,7 +139,10 @@ public:
|
||||
std::string getFullName() const;
|
||||
|
||||
/// Get the class name of the associated property editor item
|
||||
virtual const char* getEditorName() const { return ""; }
|
||||
virtual const char* getEditorName() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/// Get the type of the property in the container
|
||||
short getType() const;
|
||||
@@ -148,27 +154,31 @@ public:
|
||||
const char* getDocumentation() const;
|
||||
|
||||
/// Is called by the framework to set the father (container)
|
||||
void setContainer(PropertyContainer *Father);
|
||||
void setContainer(PropertyContainer* Father);
|
||||
|
||||
/// Get a pointer to the PropertyContainer derived class the property belongs to
|
||||
PropertyContainer *getContainer() const {return father;}
|
||||
PropertyContainer* getContainer() const
|
||||
{
|
||||
return father;
|
||||
}
|
||||
|
||||
/// Set value of property
|
||||
virtual void setPathValue(const App::ObjectIdentifier & path, const boost::any & value);
|
||||
virtual void setPathValue(const App::ObjectIdentifier& path, const boost::any& value);
|
||||
|
||||
/// Get value of property
|
||||
virtual const boost::any getPathValue(const App::ObjectIdentifier & path) const;
|
||||
virtual const boost::any getPathValue(const App::ObjectIdentifier& path) const;
|
||||
|
||||
/// Get Python value of property
|
||||
virtual bool getPyPathValue(const App::ObjectIdentifier &, Py::Object &) const {
|
||||
virtual bool getPyPathValue(const App::ObjectIdentifier&, Py::Object&) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Convert p to a canonical representation of it
|
||||
virtual App::ObjectIdentifier canonicalPath(const App::ObjectIdentifier & p) const;
|
||||
virtual App::ObjectIdentifier canonicalPath(const App::ObjectIdentifier& p) const;
|
||||
|
||||
/// Get valid paths for this property; used by auto completer
|
||||
virtual void getPaths(std::vector<App::ObjectIdentifier> & paths) const;
|
||||
virtual void getPaths(std::vector<App::ObjectIdentifier>& paths) const;
|
||||
|
||||
/** Called at the beginning of Document::afterRestore()
|
||||
*
|
||||
@@ -190,7 +200,8 @@ public:
|
||||
* with existing documents. PropertyExpressionEngine can now auto adjust
|
||||
* external references without any problem.
|
||||
*/
|
||||
virtual void afterRestore() {}
|
||||
virtual void afterRestore()
|
||||
{}
|
||||
|
||||
/** Called before calling DocumentObject::onDocumentRestored()
|
||||
*
|
||||
@@ -199,7 +210,8 @@ public:
|
||||
* is assumed ready. So, unlike Property::afterRestore(), this function is
|
||||
* called on objects with dependency order.
|
||||
*/
|
||||
virtual void onContainerRestored() {}
|
||||
virtual void onContainerRestored()
|
||||
{}
|
||||
|
||||
/** Property status handling
|
||||
*/
|
||||
@@ -207,50 +219,59 @@ public:
|
||||
/// Set the property touched
|
||||
void touch();
|
||||
/// Test if this property is touched
|
||||
inline bool isTouched() const {
|
||||
inline bool isTouched() const
|
||||
{
|
||||
return StatusBits.test(Touched);
|
||||
}
|
||||
/// Reset this property touched
|
||||
inline void purgeTouched() {
|
||||
inline void purgeTouched()
|
||||
{
|
||||
StatusBits.reset(Touched);
|
||||
}
|
||||
/// return the status bits
|
||||
inline unsigned long getStatus() const {
|
||||
inline unsigned long getStatus() const
|
||||
{
|
||||
return StatusBits.to_ulong();
|
||||
}
|
||||
inline bool testStatus(Status pos) const {
|
||||
inline bool testStatus(Status pos) const
|
||||
{
|
||||
return StatusBits.test(static_cast<size_t>(pos));
|
||||
}
|
||||
void setStatus(Status pos, bool on);
|
||||
void setStatusValue(unsigned long status);
|
||||
///Sets property editable/grayed out in property editor
|
||||
/// Sets property editable/grayed out in property editor
|
||||
void setReadOnly(bool readOnly);
|
||||
inline bool isReadOnly() const {
|
||||
inline bool isReadOnly() const
|
||||
{
|
||||
return testStatus(App::Property::ReadOnly);
|
||||
}
|
||||
/// Sets precision of properties using floating point
|
||||
/// numbers to single, the default is double.
|
||||
void setSinglePrecision(bool single) {
|
||||
void setSinglePrecision(bool single)
|
||||
{
|
||||
setStatus(App::Property::Single, single);
|
||||
}
|
||||
/// Gets precision of properties using floating point numbers
|
||||
inline bool isSinglePrecision() const {
|
||||
inline bool isSinglePrecision() const
|
||||
{
|
||||
return testStatus(App::Property::Single);
|
||||
}
|
||||
//@}
|
||||
|
||||
/// Returns a new copy of the property (mainly for Undo/Redo and transactions)
|
||||
virtual Property *Copy() const = 0;
|
||||
virtual Property* Copy() const = 0;
|
||||
/// Paste the value from the property (mainly for Undo/Redo and transactions)
|
||||
virtual void Paste(const Property &from) = 0;
|
||||
virtual void Paste(const Property& from) = 0;
|
||||
|
||||
/// Called when a child property has changed value
|
||||
virtual void hasSetChildValue(Property &) {}
|
||||
virtual void hasSetChildValue(Property&)
|
||||
{}
|
||||
/// Called before a child property changing value
|
||||
virtual void aboutToSetChildValue(Property &) {}
|
||||
virtual void aboutToSetChildValue(Property&)
|
||||
{}
|
||||
|
||||
/// Compare if this property has the same content as the given one
|
||||
virtual bool isSame(const Property &other) const;
|
||||
virtual bool isSame(const Property& other) const;
|
||||
|
||||
/** Return a unique ID for the property
|
||||
*
|
||||
@@ -258,11 +279,15 @@ public:
|
||||
* internal counter. The intention of the ID is to be used as a key for
|
||||
* mapping, instead of using the raw pointer. Because, it is possible for
|
||||
* the runtime memory allocator to reuse just deleted memory, which will
|
||||
* cause hard to debug problem if use pointer as key.
|
||||
* cause hard to debug problem if use pointer as key.
|
||||
*/
|
||||
int64_t getID() const {return _id;}
|
||||
int64_t getID() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
virtual void beforeSave() const {}
|
||||
virtual void beforeSave() const
|
||||
{}
|
||||
|
||||
friend class PropertyContainer;
|
||||
friend struct PropertyData;
|
||||
@@ -287,31 +312,32 @@ protected:
|
||||
virtual void aboutToSetValue();
|
||||
|
||||
/// Verify a path for the current property
|
||||
virtual void verifyPath(const App::ObjectIdentifier & p) const;
|
||||
virtual void verifyPath(const App::ObjectIdentifier& p) const;
|
||||
|
||||
/// Return a file name suitable for saving this property
|
||||
std::string getFileName(const char *postfix=0, const char *prefix=0) const;
|
||||
std::string getFileName(const char* postfix = 0, const char* prefix = 0) const;
|
||||
|
||||
public:
|
||||
// forbidden
|
||||
Property(const Property&) = delete;
|
||||
Property& operator = (const Property&) = delete;
|
||||
Property& operator=(const Property&) = delete;
|
||||
|
||||
private:
|
||||
// Sync status with Property_Type
|
||||
void syncType(unsigned type);
|
||||
|
||||
private:
|
||||
PropertyContainer *father{nullptr};
|
||||
const char *myName{nullptr};
|
||||
PropertyContainer* father {nullptr};
|
||||
const char* myName {nullptr};
|
||||
int64_t _id;
|
||||
|
||||
public:
|
||||
boost::signals2::signal<void (const App::Property&)> signalChanged;
|
||||
boost::signals2::signal<void(const App::Property&)> signalChanged;
|
||||
};
|
||||
|
||||
|
||||
/** A template class that is used to inhibit multiple nested calls to aboutToSetValue/hasSetValue for properties.
|
||||
/** A template class that is used to inhibit multiple nested calls to aboutToSetValue/hasSetValue
|
||||
* for properties.
|
||||
*
|
||||
* A template class that is used to inhibit multiple nested calls to
|
||||
* aboutToSetValue/hasSetValue for properties, and only invoke it on change and
|
||||
@@ -338,12 +364,15 @@ public:
|
||||
* you can manually call AtomicPropertyChange::tryInvoke(). If the condition is
|
||||
* satisfied, it will call hasSetValue() that allows exception propagation.
|
||||
*/
|
||||
template<class P> class AtomicPropertyChangeInterface {
|
||||
template<class P>
|
||||
class AtomicPropertyChangeInterface
|
||||
{
|
||||
protected:
|
||||
AtomicPropertyChangeInterface() = default;
|
||||
|
||||
public:
|
||||
class AtomicPropertyChange {
|
||||
class AtomicPropertyChange
|
||||
{
|
||||
public:
|
||||
/** Constructor
|
||||
*
|
||||
@@ -352,10 +381,13 @@ public:
|
||||
* hasn't been marked before, and calls its
|
||||
* aboutToSetValue().
|
||||
*/
|
||||
explicit AtomicPropertyChange(P & prop, bool markChange=true) : mProp(prop) {
|
||||
explicit AtomicPropertyChange(P& prop, bool markChange = true)
|
||||
: mProp(prop)
|
||||
{
|
||||
mProp.signalCounter++;
|
||||
if (markChange)
|
||||
if (markChange) {
|
||||
aboutToChange();
|
||||
}
|
||||
}
|
||||
|
||||
/** Mark the property as changed
|
||||
@@ -363,7 +395,8 @@ public:
|
||||
* It will mark the property as changed only if it has been marked
|
||||
* before, and only then will it call the property's aboutToSetValue().
|
||||
*/
|
||||
void aboutToChange() {
|
||||
void aboutToChange()
|
||||
{
|
||||
if (!mProp.hasChanged) {
|
||||
mProp.hasChanged = true;
|
||||
mProp.aboutToSetValue();
|
||||
@@ -376,7 +409,8 @@ public:
|
||||
* of the class in current call stack, it will call property's
|
||||
* hasSetValue()
|
||||
*/
|
||||
~AtomicPropertyChange() {
|
||||
~AtomicPropertyChange()
|
||||
{
|
||||
// Signal counter == 1? meaning we are the last one. Invoke
|
||||
// hasSetValue() before decrease counter to prevent recursive call
|
||||
// triggered by another AtomicPropertyChange created inside
|
||||
@@ -385,13 +419,17 @@ public:
|
||||
// Must make sure to not throw in a destructor
|
||||
try {
|
||||
mProp.hasSetValue();
|
||||
} catch(Base::Exception &e) {
|
||||
}
|
||||
catch (Base::Exception& e) {
|
||||
e.ReportException();
|
||||
} catch(...) {}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
mProp.hasChanged = false;
|
||||
}
|
||||
if (mProp.signalCounter>0)
|
||||
if (mProp.signalCounter > 0) {
|
||||
mProp.signalCounter--;
|
||||
}
|
||||
}
|
||||
|
||||
/** Check and invoke property's hasSetValue()
|
||||
@@ -401,22 +439,24 @@ public:
|
||||
*/
|
||||
// Destructor cannot throw. So we provide this function to allow error
|
||||
// propagation.
|
||||
void tryInvoke() {
|
||||
if (mProp.signalCounter==1 && mProp.hasChanged) {
|
||||
void tryInvoke()
|
||||
{
|
||||
if (mProp.signalCounter == 1 && mProp.hasChanged) {
|
||||
mProp.hasSetValue();
|
||||
if (mProp.signalCounter>0)
|
||||
if (mProp.signalCounter > 0) {
|
||||
--mProp.signalCounter;
|
||||
}
|
||||
mProp.hasChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
P & mProp; /**< Referenced to property we work on */
|
||||
P& mProp; /**< Referenced to property we work on */
|
||||
};
|
||||
|
||||
protected:
|
||||
int signalCounter{0}; /**< Counter for invoking transaction start/stop */
|
||||
bool hasChanged{false};
|
||||
int signalCounter {0}; /**< Counter for invoking transaction start/stop */
|
||||
bool hasChanged {false};
|
||||
};
|
||||
|
||||
|
||||
@@ -429,25 +469,28 @@ protected:
|
||||
class AppExport PropertyListsBase
|
||||
{
|
||||
public:
|
||||
virtual void setSize(int newSize)=0;
|
||||
virtual int getSize() const =0;
|
||||
virtual void setSize(int newSize) = 0;
|
||||
virtual int getSize() const = 0;
|
||||
|
||||
const std::set<int> &getTouchList() const {
|
||||
const std::set<int>& getTouchList() const
|
||||
{
|
||||
return _touchList;
|
||||
}
|
||||
|
||||
void clearTouchList() {
|
||||
void clearTouchList()
|
||||
{
|
||||
_touchList.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void setPyValues(const std::vector<PyObject*> &vals, const std::vector<int> &indices) {
|
||||
virtual void setPyValues(const std::vector<PyObject*>& vals, const std::vector<int>& indices)
|
||||
{
|
||||
(void)vals;
|
||||
(void)indices;
|
||||
throw Base::NotImplementedError("not implemented");
|
||||
}
|
||||
|
||||
void _setPyObject(PyObject *);
|
||||
void _setPyObject(PyObject*);
|
||||
|
||||
protected:
|
||||
std::set<int> _touchList;
|
||||
@@ -458,111 +501,141 @@ protected:
|
||||
* multiple values, not only a single value.
|
||||
* All property types which may contain more than one value inherits this class.
|
||||
*/
|
||||
class AppExport PropertyLists : public Property, public PropertyListsBase
|
||||
class AppExport PropertyLists: public Property, public PropertyListsBase
|
||||
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
void setPyObject(PyObject *obj) override {
|
||||
void setPyObject(PyObject* obj) override
|
||||
{
|
||||
_setPyObject(obj);
|
||||
}
|
||||
|
||||
// if the order of the elements in the list relevant?
|
||||
// if yes, certain operations, like restoring must make sure that the
|
||||
// order is kept despite errors.
|
||||
inline void setOrderRelevant(bool on) { this->setStatus(Status::Ordered,on); }
|
||||
inline bool isOrderRelevant() const { return this->testStatus(Status::Ordered);}
|
||||
|
||||
inline void setOrderRelevant(bool on)
|
||||
{
|
||||
this->setStatus(Status::Ordered, on);
|
||||
}
|
||||
inline bool isOrderRelevant() const
|
||||
{
|
||||
return this->testStatus(Status::Ordered);
|
||||
}
|
||||
};
|
||||
|
||||
/** Helper class to implement PropertyLists */
|
||||
template<class T, class ListT = std::vector<T>, class ParentT = PropertyLists >
|
||||
class PropertyListsT: public ParentT
|
||||
, public AtomicPropertyChangeInterface<PropertyListsT<T,ListT,ParentT> >
|
||||
template<class T, class ListT = std::vector<T>, class ParentT = PropertyLists>
|
||||
class PropertyListsT: public ParentT,
|
||||
public AtomicPropertyChangeInterface<PropertyListsT<T, ListT, ParentT>>
|
||||
{
|
||||
public:
|
||||
using const_reference = typename ListT::const_reference;
|
||||
using list_type = ListT;
|
||||
using parent_type = ParentT;
|
||||
using atomic_change = typename AtomicPropertyChangeInterface<
|
||||
PropertyListsT<T,ListT,ParentT> >::AtomicPropertyChange;
|
||||
PropertyListsT<T, ListT, ParentT>>::AtomicPropertyChange;
|
||||
|
||||
friend atomic_change;
|
||||
|
||||
virtual void setSize(int newSize, const_reference def) {
|
||||
_lValueList.resize(newSize,def);
|
||||
virtual void setSize(int newSize, const_reference def)
|
||||
{
|
||||
_lValueList.resize(newSize, def);
|
||||
}
|
||||
|
||||
void setSize(int newSize) override {
|
||||
void setSize(int newSize) override
|
||||
{
|
||||
_lValueList.resize(newSize);
|
||||
}
|
||||
|
||||
int getSize() const override {
|
||||
int getSize() const override
|
||||
{
|
||||
return static_cast<int>(_lValueList.size());
|
||||
}
|
||||
|
||||
void setValue(const_reference value) {
|
||||
void setValue(const_reference value)
|
||||
{
|
||||
ListT vals;
|
||||
vals.resize(1,value);
|
||||
vals.resize(1, value);
|
||||
setValues(vals);
|
||||
}
|
||||
|
||||
virtual void setValues(const ListT &newValues = ListT()) {
|
||||
virtual void setValues(const ListT& newValues = ListT())
|
||||
{
|
||||
atomic_change guard(*this);
|
||||
this->_touchList.clear();
|
||||
this->_lValueList = newValues;
|
||||
guard.tryInvoke();
|
||||
}
|
||||
|
||||
void setValue(const ListT &newValues = ListT()) {
|
||||
void setValue(const ListT& newValues = ListT())
|
||||
{
|
||||
setValues(newValues);
|
||||
}
|
||||
|
||||
const ListT &getValues() const{return _lValueList;}
|
||||
const ListT& getValues() const
|
||||
{
|
||||
return _lValueList;
|
||||
}
|
||||
|
||||
// alias to getValues
|
||||
const ListT &getValue() const{return getValues();}
|
||||
const ListT& getValue() const
|
||||
{
|
||||
return getValues();
|
||||
}
|
||||
|
||||
const_reference operator[] (int idx) const {return _lValueList[idx];}
|
||||
const_reference operator[](int idx) const
|
||||
{
|
||||
return _lValueList[idx];
|
||||
}
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
if (&other == this)
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
return this->getTypeId() == other.getTypeId()
|
||||
&& this->getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
|
||||
void setPyObject(PyObject *value) override {
|
||||
void setPyObject(PyObject* value) override
|
||||
{
|
||||
try {
|
||||
setValue(getPyValue(value));
|
||||
return;
|
||||
}catch(...){}
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
parent_type::setPyObject(value);
|
||||
}
|
||||
|
||||
virtual void set1Value(int index, const_reference value) {
|
||||
virtual void set1Value(int index, const_reference value)
|
||||
{
|
||||
int size = getSize();
|
||||
if (index<-1 || index>size)
|
||||
if (index < -1 || index > size) {
|
||||
throw Base::RuntimeError("index out of bound");
|
||||
}
|
||||
|
||||
atomic_change guard(*this);
|
||||
if (index==-1 || index == size) {
|
||||
if (index == -1 || index == size) {
|
||||
index = size;
|
||||
setSize(index+1,value);
|
||||
} else
|
||||
setSize(index + 1, value);
|
||||
}
|
||||
else {
|
||||
_lValueList[index] = value;
|
||||
}
|
||||
this->_touchList.insert(index);
|
||||
guard.tryInvoke();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void setPyValues(const std::vector<PyObject*>& vals, const std::vector<int>& indices) override
|
||||
{
|
||||
if (indices.empty()) {
|
||||
ListT values {};
|
||||
values.reserve(vals.size());
|
||||
for (auto *valsContent : vals) {
|
||||
for (auto* valsContent : vals) {
|
||||
values.push_back(getPyValue(valsContent));
|
||||
}
|
||||
setValues(std::move(values));
|
||||
@@ -584,6 +657,6 @@ protected:
|
||||
ListT _lValueList;
|
||||
};
|
||||
|
||||
} // namespace App
|
||||
} // namespace App
|
||||
|
||||
#endif // APP_PROPERTY_H
|
||||
#endif // APP_PROPERTY_H
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="PersistencePy"
|
||||
Name="PropertyContainerPy"
|
||||
TwinPointer="PropertyContainer"
|
||||
Twin="PropertyContainer"
|
||||
Include="App/PropertyContainer.h"
|
||||
Namespace="App"
|
||||
FatherInclude="Base/PersistencePy.h"
|
||||
<PythonExport
|
||||
Father="PersistencePy"
|
||||
Name="PropertyContainerPy"
|
||||
TwinPointer="PropertyContainer"
|
||||
Twin="PropertyContainer"
|
||||
Include="App/PropertyContainer.h"
|
||||
Namespace="App"
|
||||
FatherInclude="Base/PersistencePy.h"
|
||||
FatherNamespace="Base"
|
||||
DisableNotify="true">
|
||||
<Documentation>
|
||||
@@ -16,14 +16,14 @@
|
||||
</Documentation>
|
||||
<Methode Name="getPropertyByName">
|
||||
<Documentation>
|
||||
<UserDocu>getPropertyByName(name, checkOwner=0) -> object or Tuple
|
||||
<UserDocu>getPropertyByName(name, checkOwner=0) -> object or Tuple
|
||||
|
||||
Returns the value of a named property. Note that the returned property may not
|
||||
always belong to this container (e.g. from a linked object).
|
||||
always belong to this container (e.g. from a linked object).
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Name of the property.
|
||||
checkOwner : int
|
||||
checkOwner : int
|
||||
0: just return the property.
|
||||
1: raise exception if not found or the property does not belong to this container.
|
||||
2: return a tuple (owner, propertyValue).</UserDocu>
|
||||
@@ -31,44 +31,44 @@ checkOwner : int
|
||||
</Methode>
|
||||
<Methode Name="getPropertyTouchList">
|
||||
<Documentation>
|
||||
<UserDocu>getPropertyTouchList(name) -> tuple
|
||||
<UserDocu>getPropertyTouchList(name) -> tuple
|
||||
|
||||
Returns a list of index of touched values for list type properties.
|
||||
Returns a list of index of touched values for list type properties.
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getTypeOfProperty">
|
||||
<Documentation>
|
||||
<UserDocu>getTypeOfProperty(name) -> list
|
||||
<UserDocu>getTypeOfProperty(name) -> list
|
||||
|
||||
Returns the type of a named property. This can be a list conformed by elements in
|
||||
(Hidden, NoRecompute, NoPersist, Output, ReadOnly, Transient).
|
||||
(Hidden, NoRecompute, NoPersist, Output, ReadOnly, Transient).
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getTypeIdOfProperty">
|
||||
<Documentation>
|
||||
<UserDocu>getTypeIdOfProperty(name) -> str
|
||||
<UserDocu>getTypeIdOfProperty(name) -> str
|
||||
|
||||
Returns the C++ class name of a named property.
|
||||
Returns the C++ class name of a named property.
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setEditorMode">
|
||||
<Documentation>
|
||||
<UserDocu>setEditorMode(name, type) -> None
|
||||
<UserDocu>setEditorMode(name, type) -> None
|
||||
|
||||
Set the behaviour of the property in the property editor.
|
||||
Set the behaviour of the property in the property editor.
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name.
|
||||
type : int, sequence of str
|
||||
type : int, sequence of str
|
||||
Property type.
|
||||
0: default behaviour. 1: item is ready-only. 2: item is hidden. 3: item is hidden and read-only.
|
||||
If sequence, the available items are 'ReadOnly' and 'Hidden'.</UserDocu>
|
||||
@@ -76,121 +76,121 @@ type : int, sequence of str
|
||||
</Methode>
|
||||
<Methode Name="getEditorMode">
|
||||
<Documentation>
|
||||
<UserDocu>getEditorMode(name) -> list
|
||||
<UserDocu>getEditorMode(name) -> list
|
||||
|
||||
Get the behaviour of the property in the property editor.
|
||||
It returns a list of strings with the current mode. If the list is empty there are no
|
||||
special restrictions.
|
||||
If the list contains 'ReadOnly' then the item appears in the property editor but is
|
||||
disabled.
|
||||
If the list contains 'Hidden' then the item even doesn't appear in the property editor.
|
||||
If the list contains 'Hidden' then the item even doesn't appear in the property editor.
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getGroupOfProperty">
|
||||
<Documentation>
|
||||
<UserDocu>getGroupOfProperty(name) -> str
|
||||
<UserDocu>getGroupOfProperty(name) -> str
|
||||
|
||||
Returns the name of the group which the property belongs to in this class.
|
||||
The properties are sorted in different named groups for convenience.
|
||||
The properties are sorted in different named groups for convenience.
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setGroupOfProperty">
|
||||
<Documentation>
|
||||
<UserDocu>setGroupOfProperty(name, group) -> None
|
||||
<UserDocu>setGroupOfProperty(name, group) -> None
|
||||
|
||||
Set the name of the group of a dynamic property.
|
||||
Set the name of the group of a dynamic property.
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name.
|
||||
group : str
|
||||
group : str
|
||||
Group name.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setPropertyStatus">
|
||||
<Documentation>
|
||||
<UserDocu>setPropertyStatus(name, val) -> None
|
||||
<UserDocu>setPropertyStatus(name, val) -> None
|
||||
|
||||
Set property status.
|
||||
Set property status.
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name.
|
||||
val : int, str, sequence of str or int
|
||||
val : int, str, sequence of str or int
|
||||
Call getPropertyStatus() to get a list of supported text value.
|
||||
If the text start with '-' or the integer value is negative, then the status is cleared.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getPropertyStatus">
|
||||
<Documentation>
|
||||
<UserDocu>getPropertyStatus(name='') -> list
|
||||
<UserDocu>getPropertyStatus(name='') -> list
|
||||
|
||||
Get property status.
|
||||
Get property status.
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name. If empty, returns a list of supported text names of the status.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getDocumentationOfProperty">
|
||||
<Documentation>
|
||||
<UserDocu>getDocumentationOfProperty(name) -> str
|
||||
<UserDocu>getDocumentationOfProperty(name) -> str
|
||||
|
||||
Returns the documentation string of the property of this class.
|
||||
Returns the documentation string of the property of this class.
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setDocumentationOfProperty">
|
||||
<Documentation>
|
||||
<UserDocu>setDocumentationOfProperty(name, docstring) -> None
|
||||
<UserDocu>setDocumentationOfProperty(name, docstring) -> None
|
||||
|
||||
Set the documentation string of a dynamic property of this class.
|
||||
Set the documentation string of a dynamic property of this class.
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name.
|
||||
docstring : str
|
||||
docstring : str
|
||||
Documentation string.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getEnumerationsOfProperty">
|
||||
<Documentation>
|
||||
<UserDocu>getEnumerationsOfProperty(name) -> list or None
|
||||
<UserDocu>getEnumerationsOfProperty(name) -> list or None
|
||||
|
||||
Return all enumeration strings of the property of this class or None if not a
|
||||
PropertyEnumeration.
|
||||
PropertyEnumeration.
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="dumpPropertyContent" Keyword="true" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>dumpPropertyContent(Property, Compression=3) -> bytearray
|
||||
<UserDocu>dumpPropertyContent(Property, Compression=3) -> bytearray
|
||||
|
||||
Dumps the content of the property, both the XML representation and the additional
|
||||
data files required, into a byte representation.
|
||||
data files required, into a byte representation.
|
||||
|
||||
Property : str
|
||||
Property : str
|
||||
Property Name.
|
||||
Compression : int
|
||||
Compression : int
|
||||
Set the data compression level in the range [0, 9]. Set to 0 for no compression.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="restorePropertyContent">
|
||||
<Documentation>
|
||||
<UserDocu>restorePropertyContent(name, obj) -> None
|
||||
<UserDocu>restorePropertyContent(name, obj) -> None
|
||||
|
||||
Restore the content of the object from a byte representation as stored by `dumpPropertyContent`.
|
||||
It could be restored from any Python object implementing the buffer protocol.
|
||||
It could be restored from any Python object implementing the buffer protocol.
|
||||
|
||||
name : str
|
||||
name : str
|
||||
Property name.
|
||||
obj : buffer
|
||||
obj : buffer
|
||||
Object with buffer protocol support.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
|
||||
+208
-152
@@ -24,7 +24,7 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
#include "PropertyContainer.h"
|
||||
@@ -49,12 +49,13 @@ std::string PropertyContainerPy::representation() const
|
||||
return {"<property container>"};
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::getPropertyByName(PyObject *args)
|
||||
PyObject* PropertyContainerPy::getPropertyByName(PyObject* args)
|
||||
{
|
||||
char *pstr;
|
||||
int checkOwner=0;
|
||||
if (!PyArg_ParseTuple(args, "s|i", &pstr, &checkOwner))
|
||||
char* pstr {};
|
||||
int checkOwner = 0;
|
||||
if (!PyArg_ParseTuple(args, "s|i", &pstr, &checkOwner)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (checkOwner < 0 || checkOwner > 2) {
|
||||
PyErr_SetString(PyExc_ValueError, "'checkOwner' expected in the range [0, 2]");
|
||||
@@ -67,76 +68,87 @@ PyObject* PropertyContainerPy::getPropertyByName(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!checkOwner || (checkOwner==1 && prop->getContainer()==getPropertyContainerPtr()))
|
||||
if (!checkOwner || (checkOwner == 1 && prop->getContainer() == getPropertyContainerPtr())) {
|
||||
return prop->getPyObject();
|
||||
}
|
||||
|
||||
Py::TupleN res(Py::asObject(prop->getContainer()->getPyObject()), Py::asObject(prop->getPyObject()));
|
||||
Py::TupleN res(Py::asObject(prop->getContainer()->getPyObject()),
|
||||
Py::asObject(prop->getPyObject()));
|
||||
|
||||
return Py::new_reference_to(res);
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::getPropertyTouchList(PyObject *args)
|
||||
PyObject* PropertyContainerPy::getPropertyTouchList(PyObject* args)
|
||||
{
|
||||
char *pstr;
|
||||
if (!PyArg_ParseTuple(args, "s", &pstr))
|
||||
char* pstr {};
|
||||
if (!PyArg_ParseTuple(args, "s", &pstr)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
App::Property* prop = getPropertyContainerPtr()->getPropertyByName(pstr);
|
||||
if (prop && prop->isDerivedFrom(PropertyLists::getClassTypeId())) {
|
||||
const auto &touched = static_cast<PropertyLists*>(prop)->getTouchList();
|
||||
const auto& touched = static_cast<PropertyLists*>(prop)->getTouchList();
|
||||
Py::Tuple ret(touched.size());
|
||||
int i=0;
|
||||
for(int idx : touched)
|
||||
ret.setItem(i++,Py::Long(idx));
|
||||
int i = 0;
|
||||
for (int idx : touched) {
|
||||
ret.setItem(i++, Py::Long(idx));
|
||||
}
|
||||
return Py::new_reference_to(ret);
|
||||
}
|
||||
else if (!prop) {
|
||||
PyErr_Format(PyExc_AttributeError, "Property container has no property '%s'", pstr);
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_AttributeError, "Property '%s' is not of list type", pstr);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::getTypeOfProperty(PyObject *args)
|
||||
{
|
||||
Py::List ret;
|
||||
char *pstr;
|
||||
if (!PyArg_ParseTuple(args, "s", &pstr))
|
||||
return nullptr;
|
||||
|
||||
Property* prop = getPropertyContainerPtr()->getPropertyByName(pstr);
|
||||
if (!prop) {
|
||||
PyErr_Format(PyExc_AttributeError, "Property container has no property '%s'", pstr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
short Type = prop->getType();
|
||||
if (Type & Prop_ReadOnly)
|
||||
PyErr_Format(PyExc_AttributeError, "Property '%s' is not of list type", pstr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::getTypeOfProperty(PyObject* args)
|
||||
{
|
||||
Py::List ret;
|
||||
char* pstr {};
|
||||
if (!PyArg_ParseTuple(args, "s", &pstr)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Property* prop = getPropertyContainerPtr()->getPropertyByName(pstr);
|
||||
if (!prop) {
|
||||
PyErr_Format(PyExc_AttributeError, "Property container has no property '%s'", pstr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
short Type = prop->getType();
|
||||
if (Type & Prop_ReadOnly) {
|
||||
ret.append(Py::String("ReadOnly"));
|
||||
if (Type & Prop_Transient)
|
||||
}
|
||||
if (Type & Prop_Transient) {
|
||||
ret.append(Py::String("Transient"));
|
||||
if (Type & Prop_Hidden)
|
||||
}
|
||||
if (Type & Prop_Hidden) {
|
||||
ret.append(Py::String("Hidden"));
|
||||
if (Type & Prop_Output)
|
||||
}
|
||||
if (Type & Prop_Output) {
|
||||
ret.append(Py::String("Output"));
|
||||
if (Type & Prop_NoRecompute)
|
||||
}
|
||||
if (Type & Prop_NoRecompute) {
|
||||
ret.append(Py::String("NoRecompute"));
|
||||
if (Type & Prop_NoPersist)
|
||||
}
|
||||
if (Type & Prop_NoPersist) {
|
||||
ret.append(Py::String("NoPersist"));
|
||||
}
|
||||
|
||||
return Py::new_reference_to(ret);
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::getTypeIdOfProperty(PyObject *args)
|
||||
PyObject* PropertyContainerPy::getTypeIdOfProperty(PyObject* args)
|
||||
{
|
||||
char *pstr;
|
||||
if (!PyArg_ParseTuple(args, "s", &pstr))
|
||||
char* pstr {};
|
||||
if (!PyArg_ParseTuple(args, "s", &pstr)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Property* prop = getPropertyContainerPtr()->getPropertyByName(pstr);
|
||||
Property* prop = getPropertyContainerPtr()->getPropertyByName(pstr);
|
||||
if (!prop) {
|
||||
PyErr_Format(PyExc_AttributeError, "Property container has no property '%s'", pstr);
|
||||
return nullptr;
|
||||
@@ -146,10 +158,10 @@ PyObject* PropertyContainerPy::getTypeIdOfProperty(PyObject *args)
|
||||
return Py::new_reference_to(str);
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::setEditorMode(PyObject *args)
|
||||
PyObject* PropertyContainerPy::setEditorMode(PyObject* args)
|
||||
{
|
||||
char* name;
|
||||
short type;
|
||||
char* name {};
|
||||
short type {};
|
||||
if (PyArg_ParseTuple(args, "sh", &name, &type)) {
|
||||
App::Property* prop = getPropertyContainerPtr()->getPropertyByName(name);
|
||||
if (!prop) {
|
||||
@@ -166,7 +178,7 @@ PyObject* PropertyContainerPy::setEditorMode(PyObject *args)
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
PyObject *iter;
|
||||
PyObject* iter {};
|
||||
if (PyArg_ParseTuple(args, "sO", &name, &iter)) {
|
||||
if (PyTuple_Check(iter) || PyList_Check(iter)) {
|
||||
Py::Sequence seq(iter);
|
||||
@@ -180,12 +192,14 @@ PyObject* PropertyContainerPy::setEditorMode(PyObject *args)
|
||||
std::bitset<32> status(prop->getStatus());
|
||||
status.reset(Property::ReadOnly);
|
||||
status.reset(Property::Hidden);
|
||||
for (Py::Sequence::iterator it = seq.begin();it!=seq.end();++it) {
|
||||
for (Py::Sequence::iterator it = seq.begin(); it != seq.end(); ++it) {
|
||||
std::string str = static_cast<std::string>(Py::String(*it));
|
||||
if (str == "ReadOnly")
|
||||
if (str == "ReadOnly") {
|
||||
status.set(Property::ReadOnly);
|
||||
else if (str == "Hidden")
|
||||
}
|
||||
else if (str == "Hidden") {
|
||||
status.set(Property::Hidden);
|
||||
}
|
||||
}
|
||||
prop->setStatusValue(status.to_ulong());
|
||||
|
||||
@@ -193,13 +207,15 @@ PyObject* PropertyContainerPy::setEditorMode(PyObject *args)
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "First argument must be str, second can be int, list or tuple");
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"First argument must be str, second can be int, list or tuple");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static const std::map<std::string, int> &getStatusMap() {
|
||||
static std::map<std::string,int> statusMap;
|
||||
if(statusMap.empty()) {
|
||||
static const std::map<std::string, int>& getStatusMap()
|
||||
{
|
||||
static std::map<std::string, int> statusMap;
|
||||
if (statusMap.empty()) {
|
||||
statusMap["Immutable"] = Property::Immutable;
|
||||
statusMap["ReadOnly"] = Property::ReadOnly;
|
||||
statusMap["Hidden"] = Property::Hidden;
|
||||
@@ -217,12 +233,13 @@ static const std::map<std::string, int> &getStatusMap() {
|
||||
return statusMap;
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::setPropertyStatus(PyObject *args)
|
||||
PyObject* PropertyContainerPy::setPropertyStatus(PyObject* args)
|
||||
{
|
||||
char* name {};
|
||||
PyObject* pyValue {};
|
||||
if (!PyArg_ParseTuple(args, "sO", &name, &pyValue))
|
||||
if (!PyArg_ParseTuple(args, "sO", &name, &pyValue)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
App::Property* prop = getPropertyContainerPtr()->getPropertyByName(name);
|
||||
if (!prop) {
|
||||
@@ -247,7 +264,7 @@ PyObject* PropertyContainerPy::setPropertyStatus(PyObject *args)
|
||||
for (const auto& item : items) {
|
||||
bool value = true;
|
||||
if (item.isString()) {
|
||||
const auto &statusMap = getStatusMap();
|
||||
const auto& statusMap = getStatusMap();
|
||||
auto v = static_cast<std::string>(Py::String(item));
|
||||
if (v.size() > 1 && v[0] == '-') {
|
||||
value = false;
|
||||
@@ -288,17 +305,19 @@ PyObject* PropertyContainerPy::setPropertyStatus(PyObject *args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::getPropertyStatus(PyObject *args)
|
||||
PyObject* PropertyContainerPy::getPropertyStatus(PyObject* args)
|
||||
{
|
||||
const char* name = "";
|
||||
if (!PyArg_ParseTuple(args, "|s", &name))
|
||||
if (!PyArg_ParseTuple(args, "|s", &name)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Py::List ret;
|
||||
const auto &statusMap = getStatusMap();
|
||||
const auto& statusMap = getStatusMap();
|
||||
if (!name[0]) {
|
||||
for(auto &v : statusMap)
|
||||
for (auto& v : statusMap) {
|
||||
ret.append(Py::String(v.first.c_str()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
App::Property* prop = getPropertyContainerPtr()->getPropertyByName(name);
|
||||
@@ -308,32 +327,37 @@ PyObject* PropertyContainerPy::getPropertyStatus(PyObject *args)
|
||||
}
|
||||
|
||||
auto linkProp = Base::freecad_dynamic_cast<App::PropertyLinkBase>(prop);
|
||||
if (linkProp && linkProp->testFlag(App::PropertyLinkBase::LinkAllowPartial))
|
||||
if (linkProp && linkProp->testFlag(App::PropertyLinkBase::LinkAllowPartial)) {
|
||||
ret.append(Py::String("AllowPartial"));
|
||||
}
|
||||
|
||||
std::bitset<32> bits(prop->getStatus());
|
||||
for(size_t i=1; i<bits.size(); ++i) {
|
||||
if(!bits[i]) continue;
|
||||
for (size_t i = 1; i < bits.size(); ++i) {
|
||||
if (!bits[i]) {
|
||||
continue;
|
||||
}
|
||||
bool found = false;
|
||||
for(auto &v : statusMap) {
|
||||
if(v.second == static_cast<int>(i)) {
|
||||
for (auto& v : statusMap) {
|
||||
if (v.second == static_cast<int>(i)) {
|
||||
ret.append(Py::String(v.first.c_str()));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
if (!found) {
|
||||
ret.append(Py::Int(static_cast<long>(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Py::new_reference_to(ret);
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::getEditorMode(PyObject *args)
|
||||
PyObject* PropertyContainerPy::getEditorMode(PyObject* args)
|
||||
{
|
||||
char* name;
|
||||
if (!PyArg_ParseTuple(args, "s", &name))
|
||||
char* name {};
|
||||
if (!PyArg_ParseTuple(args, "s", &name)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
App::Property* prop = getPropertyContainerPtr()->getPropertyByName(name);
|
||||
if (!prop) {
|
||||
@@ -343,20 +367,23 @@ PyObject* PropertyContainerPy::getEditorMode(PyObject *args)
|
||||
|
||||
Py::List ret;
|
||||
if (prop) {
|
||||
short Type = prop->getType();
|
||||
if ((prop->testStatus(Property::ReadOnly)) || (Type & Prop_ReadOnly))
|
||||
short Type = prop->getType();
|
||||
if ((prop->testStatus(Property::ReadOnly)) || (Type & Prop_ReadOnly)) {
|
||||
ret.append(Py::String("ReadOnly"));
|
||||
if ((prop->testStatus(Property::Hidden)) || (Type & Prop_Hidden))
|
||||
}
|
||||
if ((prop->testStatus(Property::Hidden)) || (Type & Prop_Hidden)) {
|
||||
ret.append(Py::String("Hidden"));
|
||||
}
|
||||
}
|
||||
return Py::new_reference_to(ret);
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::getGroupOfProperty(PyObject *args)
|
||||
PyObject* PropertyContainerPy::getGroupOfProperty(PyObject* args)
|
||||
{
|
||||
char *pstr;
|
||||
if (!PyArg_ParseTuple(args, "s", &pstr))
|
||||
char* pstr {};
|
||||
if (!PyArg_ParseTuple(args, "s", &pstr)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Property* prop = getPropertyContainerPtr()->getPropertyByName(pstr);
|
||||
if (!prop) {
|
||||
@@ -365,37 +392,44 @@ PyObject* PropertyContainerPy::getGroupOfProperty(PyObject *args)
|
||||
}
|
||||
|
||||
const char* Group = getPropertyContainerPtr()->getPropertyGroup(prop);
|
||||
if (Group)
|
||||
if (Group) {
|
||||
return Py::new_reference_to(Py::String(Group));
|
||||
else
|
||||
}
|
||||
else {
|
||||
return Py::new_reference_to(Py::String(""));
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::setGroupOfProperty(PyObject *args)
|
||||
PyObject* PropertyContainerPy::setGroupOfProperty(PyObject* args)
|
||||
{
|
||||
char *pstr;
|
||||
char *group;
|
||||
if (!PyArg_ParseTuple(args, "ss", &pstr, &group))
|
||||
char* pstr {};
|
||||
char* group {};
|
||||
if (!PyArg_ParseTuple(args, "ss", &pstr, &group)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PY_TRY {
|
||||
PY_TRY
|
||||
{
|
||||
Property* prop = getPropertyContainerPtr()->getDynamicPropertyByName(pstr);
|
||||
if (!prop) {
|
||||
PyErr_Format(PyExc_AttributeError, "Property container has no dynamic property '%s'", pstr);
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"Property container has no dynamic property '%s'",
|
||||
pstr);
|
||||
return nullptr;
|
||||
}
|
||||
prop->getContainer()->changeDynamicProperty(prop,group,nullptr);
|
||||
prop->getContainer()->changeDynamicProperty(prop, group, nullptr);
|
||||
Py_Return;
|
||||
}
|
||||
PY_CATCH
|
||||
}
|
||||
|
||||
|
||||
PyObject* PropertyContainerPy::getDocumentationOfProperty(PyObject *args)
|
||||
PyObject* PropertyContainerPy::getDocumentationOfProperty(PyObject* args)
|
||||
{
|
||||
char *pstr;
|
||||
if (!PyArg_ParseTuple(args, "s", &pstr))
|
||||
char* pstr {};
|
||||
if (!PyArg_ParseTuple(args, "s", &pstr)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Property* prop = getPropertyContainerPtr()->getPropertyByName(pstr);
|
||||
if (!prop) {
|
||||
@@ -404,36 +438,43 @@ PyObject* PropertyContainerPy::getDocumentationOfProperty(PyObject *args)
|
||||
}
|
||||
|
||||
const char* docstr = getPropertyContainerPtr()->getPropertyDocumentation(prop);
|
||||
if (docstr)
|
||||
if (docstr) {
|
||||
return Py::new_reference_to(Py::String(docstr));
|
||||
else
|
||||
}
|
||||
else {
|
||||
return Py::new_reference_to(Py::String(""));
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::setDocumentationOfProperty(PyObject *args)
|
||||
PyObject* PropertyContainerPy::setDocumentationOfProperty(PyObject* args)
|
||||
{
|
||||
char *pstr;
|
||||
char *doc;
|
||||
if (!PyArg_ParseTuple(args, "ss", &pstr, &doc))
|
||||
char* pstr {};
|
||||
char* doc {};
|
||||
if (!PyArg_ParseTuple(args, "ss", &pstr, &doc)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PY_TRY {
|
||||
PY_TRY
|
||||
{
|
||||
Property* prop = getPropertyContainerPtr()->getDynamicPropertyByName(pstr);
|
||||
if (!prop) {
|
||||
PyErr_Format(PyExc_AttributeError, "Property container has no dynamic property '%s'", pstr);
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"Property container has no dynamic property '%s'",
|
||||
pstr);
|
||||
return nullptr;
|
||||
}
|
||||
prop->getContainer()->changeDynamicProperty(prop,nullptr,doc);
|
||||
prop->getContainer()->changeDynamicProperty(prop, nullptr, doc);
|
||||
Py_Return;
|
||||
}
|
||||
PY_CATCH
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::getEnumerationsOfProperty(PyObject *args)
|
||||
PyObject* PropertyContainerPy::getEnumerationsOfProperty(PyObject* args)
|
||||
{
|
||||
char *pstr;
|
||||
if (!PyArg_ParseTuple(args, "s", &pstr))
|
||||
char* pstr {};
|
||||
if (!PyArg_ParseTuple(args, "s", &pstr)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Property* prop = getPropertyContainerPtr()->getPropertyByName(pstr);
|
||||
if (!prop) {
|
||||
@@ -441,13 +482,14 @@ PyObject* PropertyContainerPy::getEnumerationsOfProperty(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PropertyEnumeration *enumProp = dynamic_cast<PropertyEnumeration*>(prop);
|
||||
if (!enumProp)
|
||||
PropertyEnumeration* enumProp = dynamic_cast<PropertyEnumeration*>(prop);
|
||||
if (!enumProp) {
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
std::vector<std::string> enumerations = enumProp->getEnumVector();
|
||||
Py::List ret;
|
||||
for (const auto & it : enumerations) {
|
||||
for (const auto& it : enumerations) {
|
||||
ret.append(Py::String(it));
|
||||
}
|
||||
return Py::new_reference_to(ret);
|
||||
@@ -456,24 +498,30 @@ PyObject* PropertyContainerPy::getEnumerationsOfProperty(PyObject *args)
|
||||
Py::List PropertyContainerPy::getPropertiesList() const
|
||||
{
|
||||
Py::List ret;
|
||||
std::map<std::string,Property*> Map;
|
||||
std::map<std::string, Property*> Map;
|
||||
|
||||
getPropertyContainerPtr()->getPropertyMap(Map);
|
||||
|
||||
for (std::map<std::string,Property*>::const_iterator It=Map.begin(); It!=Map.end(); ++It)
|
||||
ret.append(Py::String(It->first));
|
||||
for (const auto& It : Map) {
|
||||
ret.append(Py::String(It.first));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PyObject* PropertyContainerPy::dumpPropertyContent(PyObject *args, PyObject *kwds)
|
||||
PyObject* PropertyContainerPy::dumpPropertyContent(PyObject* args, PyObject* kwds)
|
||||
{
|
||||
int compression = 3;
|
||||
const char* property;
|
||||
static const std::array<const char *, 3> kwds_def {"Property", "Compression", nullptr};
|
||||
const char* property {};
|
||||
static const std::array<const char*, 3> kwds_def {"Property", "Compression", nullptr};
|
||||
PyErr_Clear();
|
||||
if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "s|i", kwds_def, &property, &compression)) {
|
||||
if (!Base::Wrapped_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"s|i",
|
||||
kwds_def,
|
||||
&property,
|
||||
&compression)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -483,35 +531,36 @@ PyObject* PropertyContainerPy::dumpPropertyContent(PyObject *args, PyObject *kwd
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//setup the stream. the in flag is needed to make "read" work
|
||||
std::stringstream stream(std::stringstream::out | std::stringstream::in | std::stringstream::binary);
|
||||
// setup the stream. the in flag is needed to make "read" work
|
||||
std::stringstream stream(std::stringstream::out | std::stringstream::in
|
||||
| std::stringstream::binary);
|
||||
try {
|
||||
prop->dumpToStream(stream, compression);
|
||||
}
|
||||
catch (...) {
|
||||
PyErr_SetString(PyExc_IOError, "Unable to parse content into binary representation");
|
||||
return nullptr;
|
||||
PyErr_SetString(PyExc_IOError, "Unable to parse content into binary representation");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//build the byte array with correct size
|
||||
if (!stream.seekp(0, stream.end)) {
|
||||
// build the byte array with correct size
|
||||
if (!stream.seekp(0, std::stringstream::end)) {
|
||||
PyErr_SetString(PyExc_IOError, "Unable to find end of stream");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::stringstream::pos_type offset = stream.tellp();
|
||||
if (!stream.seekg(0, stream.beg)) {
|
||||
if (!stream.seekg(0, std::stringstream::beg)) {
|
||||
PyErr_SetString(PyExc_IOError, "Unable to find begin of stream");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ba = PyByteArray_FromStringAndSize(nullptr, offset);
|
||||
|
||||
//use the buffer protocol to access the underlying array and write into it
|
||||
// use the buffer protocol to access the underlying array and write into it
|
||||
Py_buffer buf = Py_buffer();
|
||||
PyObject_GetBuffer(ba, &buf, PyBUF_WRITABLE);
|
||||
try {
|
||||
if(!stream.read((char*)buf.buf, offset)) {
|
||||
if (!stream.read((char*)buf.buf, offset)) {
|
||||
PyErr_SetString(PyExc_IOError, "Error copying data into byte array");
|
||||
return nullptr;
|
||||
}
|
||||
@@ -526,12 +575,13 @@ PyObject* PropertyContainerPy::dumpPropertyContent(PyObject *args, PyObject *kwd
|
||||
return ba;
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::restorePropertyContent(PyObject *args)
|
||||
PyObject* PropertyContainerPy::restorePropertyContent(PyObject* args)
|
||||
{
|
||||
PyObject* buffer;
|
||||
char* property;
|
||||
if( !PyArg_ParseTuple(args, "sO", &property, &buffer) )
|
||||
PyObject* buffer {};
|
||||
char* property {};
|
||||
if (!PyArg_ParseTuple(args, "sO", &property, &buffer)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Property* prop = getPropertyContainerPtr()->getPropertyByName(property);
|
||||
if (!prop) {
|
||||
@@ -539,28 +589,29 @@ PyObject* PropertyContainerPy::restorePropertyContent(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//check if it really is a buffer
|
||||
if( !PyObject_CheckBuffer(buffer) ) {
|
||||
// check if it really is a buffer
|
||||
if (!PyObject_CheckBuffer(buffer)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Must be a buffer object");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Py_buffer buf;
|
||||
if(PyObject_GetBuffer(buffer, &buf, PyBUF_SIMPLE) < 0)
|
||||
if (PyObject_GetBuffer(buffer, &buf, PyBUF_SIMPLE) < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(!PyBuffer_IsContiguous(&buf, 'C')) {
|
||||
if (!PyBuffer_IsContiguous(&buf, 'C')) {
|
||||
PyErr_SetString(PyExc_TypeError, "Buffer must be contiguous");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//check if it really is a buffer
|
||||
// check if it really is a buffer
|
||||
try {
|
||||
using Device = boost::iostreams::basic_array_source<char>;
|
||||
boost::iostreams::stream<Device> stream((char*)buf.buf, buf.len);
|
||||
prop->restoreFromStream(stream);
|
||||
}
|
||||
catch(...) {
|
||||
catch (...) {
|
||||
PyErr_SetString(PyExc_IOError, "Unable to restore content");
|
||||
return nullptr;
|
||||
}
|
||||
@@ -568,13 +619,13 @@ PyObject* PropertyContainerPy::restorePropertyContent(PyObject *args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject *PropertyContainerPy::getCustomAttributes(const char* attr) const
|
||||
PyObject* PropertyContainerPy::getCustomAttributes(const char* attr) const
|
||||
{
|
||||
// search in PropertyList
|
||||
if(FC_LOG_INSTANCE.level()>FC_LOGLEVEL_TRACE) {
|
||||
if (FC_LOG_INSTANCE.level() > FC_LOGLEVEL_TRACE) {
|
||||
FC_TRACE("Get property " << attr);
|
||||
}
|
||||
Property *prop = getPropertyContainerPtr()->getPropertyByName(attr);
|
||||
Property* prop = getPropertyContainerPtr()->getPropertyByName(attr);
|
||||
if (prop) {
|
||||
PyObject* pyobj = prop->getPyObject();
|
||||
if (!pyobj && PyErr_Occurred()) {
|
||||
@@ -583,44 +634,49 @@ PyObject *PropertyContainerPy::getCustomAttributes(const char* attr) const
|
||||
}
|
||||
return pyobj;
|
||||
}
|
||||
else if (Base::streq(attr, "__dict__")) {
|
||||
if (Base::streq(attr, "__dict__")) {
|
||||
// get the properties to the C++ PropertyContainer class
|
||||
std::map<std::string,App::Property*> Map;
|
||||
std::map<std::string, App::Property*> Map;
|
||||
getPropertyContainerPtr()->getPropertyMap(Map);
|
||||
|
||||
Py::Dict dict;
|
||||
for (const auto & it : Map) {
|
||||
for (const auto& it : Map) {
|
||||
dict.setItem(it.first, Py::String(""));
|
||||
}
|
||||
return Py::new_reference_to(dict);
|
||||
}
|
||||
///FIXME: For v0.20: Do not use stuff from Part module here!
|
||||
else if(Base::streq(attr,"Shape") && getPropertyContainerPtr()->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
|
||||
/// FIXME: For v0.20: Do not use stuff from Part module here!
|
||||
if (Base::streq(attr, "Shape")
|
||||
&& getPropertyContainerPtr()->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
|
||||
// Special treatment of Shape property
|
||||
static PyObject *_getShape = nullptr;
|
||||
if(!_getShape) {
|
||||
static PyObject* _getShape = nullptr;
|
||||
if (!_getShape) {
|
||||
_getShape = Py_None;
|
||||
PyObject *mod = PyImport_ImportModule("Part");
|
||||
if(!mod) {
|
||||
PyObject* mod = PyImport_ImportModule("Part");
|
||||
if (!mod) {
|
||||
PyErr_Clear();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Py::Object pyMod = Py::asObject(mod);
|
||||
if(pyMod.hasAttr("getShape"))
|
||||
if (pyMod.hasAttr("getShape")) {
|
||||
_getShape = Py::new_reference_to(pyMod.getAttr("getShape"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(_getShape != Py_None) {
|
||||
if (_getShape != Py_None) {
|
||||
Py::Tuple args(1);
|
||||
args.setItem(0,Py::Object(const_cast<PropertyContainerPy*>(this)));
|
||||
args.setItem(0, Py::Object(const_cast<PropertyContainerPy*>(this)));
|
||||
auto res = PyObject_CallObject(_getShape, args.ptr());
|
||||
if(!res)
|
||||
if (!res) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
else {
|
||||
Py::Object pyres(res,true);
|
||||
if(pyres.hasAttr("isNull")) {
|
||||
Py::Object pyres(res, true);
|
||||
if (pyres.hasAttr("isNull")) {
|
||||
Py::Callable func(pyres.getAttr("isNull"));
|
||||
if(!func.apply().isTrue())
|
||||
if (!func.apply().isTrue()) {
|
||||
return Py::new_reference_to(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -629,13 +685,13 @@ PyObject *PropertyContainerPy::getCustomAttributes(const char* attr) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int PropertyContainerPy::setCustomAttributes(const char* attr, PyObject *obj)
|
||||
int PropertyContainerPy::setCustomAttributes(const char* attr, PyObject* obj)
|
||||
{
|
||||
// search in PropertyList
|
||||
Property *prop = getPropertyContainerPtr()->getPropertyByName(attr);
|
||||
Property* prop = getPropertyContainerPtr()->getPropertyByName(attr);
|
||||
if (prop) {
|
||||
// Read-only attributes must not be set over its Python interface
|
||||
if(prop->testStatus(Property::Immutable)) {
|
||||
if (prop->testStatus(Property::Immutable)) {
|
||||
std::stringstream s;
|
||||
s << "Object attribute '" << attr << "' is read-only";
|
||||
throw Py::AttributeError(s.str());
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,12 +31,14 @@
|
||||
#include <App/PropertyLinks.h>
|
||||
#include <set>
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
class Writer;
|
||||
class XMLReader;
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
namespace App {
|
||||
namespace App
|
||||
{
|
||||
|
||||
class DocumentObject;
|
||||
class DocumentObjectExecReturn;
|
||||
@@ -44,84 +46,96 @@ class ObjectIdentifier;
|
||||
class Expression;
|
||||
using ExpressionPtr = std::unique_ptr<Expression>;
|
||||
|
||||
class AppExport PropertyExpressionContainer : public App::PropertyXLinkContainer
|
||||
class AppExport PropertyExpressionContainer: public App::PropertyXLinkContainer
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
PropertyExpressionContainer();
|
||||
~PropertyExpressionContainer() override;
|
||||
|
||||
virtual std::map<App::ObjectIdentifier, const App::Expression*> getExpressions() const = 0;
|
||||
virtual void setExpressions(std::map<App::ObjectIdentifier, App::ExpressionPtr> &&exprs) = 0;
|
||||
virtual void setExpressions(std::map<App::ObjectIdentifier, App::ExpressionPtr>&& exprs) = 0;
|
||||
|
||||
protected:
|
||||
virtual void onRelabeledDocument(const App::Document &doc) = 0;
|
||||
virtual void onRelabeledDocument(const App::Document& doc) = 0;
|
||||
|
||||
private:
|
||||
static void slotRelabelDocument(const App::Document &doc);
|
||||
static void slotRelabelDocument(const App::Document& doc);
|
||||
};
|
||||
|
||||
class AppExport PropertyExpressionEngine : public App::PropertyExpressionContainer,
|
||||
private App::AtomicPropertyChangeInterface<PropertyExpressionEngine>
|
||||
class AppExport PropertyExpressionEngine
|
||||
: public App::PropertyExpressionContainer,
|
||||
private App::AtomicPropertyChangeInterface<PropertyExpressionEngine>
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
|
||||
void updateElementReference(
|
||||
App::DocumentObject *feature, bool reverse=false, bool notify=false) override;
|
||||
void updateElementReference(App::DocumentObject* feature,
|
||||
bool reverse = false,
|
||||
bool notify = false) override;
|
||||
bool referenceChanged() const override;
|
||||
bool adjustLink(const std::set<App::DocumentObject *> &inList) override;
|
||||
Property *CopyOnImportExternal(const std::map<std::string,std::string> &nameMap) const override;
|
||||
Property *CopyOnLabelChange(App::DocumentObject *obj,
|
||||
const std::string &ref, const char *newLabel) const override;
|
||||
Property *CopyOnLinkReplace(const App::DocumentObject *parent,
|
||||
App::DocumentObject *oldObj, App::DocumentObject *newObj) const override;
|
||||
bool adjustLink(const std::set<App::DocumentObject*>& inList) override;
|
||||
Property*
|
||||
CopyOnImportExternal(const std::map<std::string, std::string>& nameMap) const override;
|
||||
Property* CopyOnLabelChange(App::DocumentObject* obj,
|
||||
const std::string& ref,
|
||||
const char* newLabel) const override;
|
||||
Property* CopyOnLinkReplace(const App::DocumentObject* parent,
|
||||
App::DocumentObject* oldObj,
|
||||
App::DocumentObject* newObj) const override;
|
||||
|
||||
using ValidatorFunc = std::function<std::string (const App::ObjectIdentifier & path, std::shared_ptr<const App::Expression> expr)>;
|
||||
using ValidatorFunc = std::function<std::string(const App::ObjectIdentifier& path,
|
||||
std::shared_ptr<const App::Expression> expr)>;
|
||||
|
||||
/**
|
||||
* @brief The ExpressionInfo struct encapsulates an expression.
|
||||
*/
|
||||
|
||||
struct ExpressionInfo {
|
||||
struct ExpressionInfo
|
||||
{
|
||||
std::shared_ptr<App::Expression> expression; /**< The actual expression tree */
|
||||
bool busy;
|
||||
|
||||
explicit ExpressionInfo(std::shared_ptr<App::Expression> expression = std::shared_ptr<App::Expression>()) {
|
||||
explicit ExpressionInfo(
|
||||
std::shared_ptr<App::Expression> expression = std::shared_ptr<App::Expression>())
|
||||
{
|
||||
this->expression = expression;
|
||||
this->busy = false;
|
||||
}
|
||||
|
||||
ExpressionInfo(const ExpressionInfo &) = default;
|
||||
ExpressionInfo(const ExpressionInfo&) = default;
|
||||
|
||||
ExpressionInfo & operator=(const ExpressionInfo &) = default;
|
||||
ExpressionInfo& operator=(const ExpressionInfo&) = default;
|
||||
};
|
||||
|
||||
PropertyExpressionEngine();
|
||||
~PropertyExpressionEngine() override;
|
||||
|
||||
unsigned int getMemSize () const override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
std::map<App::ObjectIdentifier, const App::Expression*> getExpressions() const override;
|
||||
void setExpressions(std::map<App::ObjectIdentifier, App::ExpressionPtr> &&exprs) override;
|
||||
void onRelabeledDocument(const App::Document &doc) override;
|
||||
void setExpressions(std::map<App::ObjectIdentifier, App::ExpressionPtr>&& exprs) override;
|
||||
void onRelabeledDocument(const App::Document& doc) override;
|
||||
|
||||
void setValue() { } // Dummy
|
||||
void setValue()
|
||||
{} // Dummy
|
||||
|
||||
Property *Copy() const override;
|
||||
Property* Copy() const override;
|
||||
|
||||
void Paste(const Property &from) override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
void Save (Base::Writer & writer) const override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
void setValue(const App::ObjectIdentifier &path, std::shared_ptr<App::Expression> expr);
|
||||
void setValue(const App::ObjectIdentifier& path, std::shared_ptr<App::Expression> expr);
|
||||
|
||||
const boost::any getPathValue(const App::ObjectIdentifier & path) const override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier& path) const override;
|
||||
|
||||
/// Execute options
|
||||
enum ExecuteOption {
|
||||
enum ExecuteOption
|
||||
{
|
||||
/// Execute all expression
|
||||
ExecuteAll,
|
||||
/// Execute only output property bindings
|
||||
@@ -135,67 +149,74 @@ public:
|
||||
*
|
||||
* @param option: execution option, see ExecuteOption.
|
||||
*/
|
||||
DocumentObjectExecReturn * execute(ExecuteOption option=ExecuteAll, bool *touched=nullptr);
|
||||
DocumentObjectExecReturn* execute(ExecuteOption option = ExecuteAll, bool* touched = nullptr);
|
||||
|
||||
void getPathsToDocumentObject(DocumentObject*, std::vector<App::ObjectIdentifier> & paths) const;
|
||||
void getPathsToDocumentObject(DocumentObject*, std::vector<App::ObjectIdentifier>& paths) const;
|
||||
|
||||
bool depsAreTouched() const;
|
||||
|
||||
/* Expression validator */
|
||||
void setValidator(ValidatorFunc f) { validator = f; }
|
||||
void setValidator(ValidatorFunc f)
|
||||
{
|
||||
validator = f;
|
||||
}
|
||||
|
||||
std::string validateExpression(const App::ObjectIdentifier & path, std::shared_ptr<const App::Expression> expr) const;
|
||||
std::string validateExpression(const App::ObjectIdentifier& path,
|
||||
std::shared_ptr<const App::Expression> expr) const;
|
||||
|
||||
void renameExpressions(const std::map<App::ObjectIdentifier, App::ObjectIdentifier> &paths);
|
||||
void renameExpressions(const std::map<App::ObjectIdentifier, App::ObjectIdentifier>& paths);
|
||||
|
||||
void renameObjectIdentifiers(const std::map<App::ObjectIdentifier, App::ObjectIdentifier> & paths);
|
||||
void
|
||||
renameObjectIdentifiers(const std::map<App::ObjectIdentifier, App::ObjectIdentifier>& paths);
|
||||
|
||||
App::ObjectIdentifier canonicalPath(const App::ObjectIdentifier &p) const override;
|
||||
App::ObjectIdentifier canonicalPath(const App::ObjectIdentifier& p) const override;
|
||||
|
||||
size_t numExpressions() const;
|
||||
|
||||
///signal called when an expression was changed
|
||||
boost::signals2::signal<void (const App::ObjectIdentifier &)> expressionChanged;
|
||||
/// signal called when an expression was changed
|
||||
boost::signals2::signal<void(const App::ObjectIdentifier&)> expressionChanged;
|
||||
|
||||
void afterRestore() override;
|
||||
void onContainerRestored() override;
|
||||
|
||||
void getLinksTo(std::vector<App::ObjectIdentifier> &identifiers,
|
||||
App::DocumentObject *obj,
|
||||
const char *subname=nullptr,
|
||||
bool all=false) const override;
|
||||
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;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject*) override;
|
||||
|
||||
protected:
|
||||
void hasSetValue() override;
|
||||
|
||||
private:
|
||||
|
||||
using DiGraph = boost::adjacency_list< boost::listS, boost::vecS, boost::directedS >;
|
||||
using DiGraph = boost::adjacency_list<boost::listS, boost::vecS, boost::directedS>;
|
||||
using Edge = std::pair<int, int>;
|
||||
// Note: use std::map instead of unordered_map to keep the binding order stable
|
||||
#if defined(FC_OS_MACOSX) || defined(FC_OS_BSD) || defined(_LIBCPP_VERSION)
|
||||
// Note: use std::map instead of unordered_map to keep the binding order stable
|
||||
#if defined(FC_OS_MACOSX) || defined(FC_OS_BSD) || defined(_LIBCPP_VERSION)
|
||||
using ExpressionMap = std::map<App::ObjectIdentifier, ExpressionInfo>;
|
||||
#else
|
||||
#else
|
||||
using ExpressionMap = std::map<const App::ObjectIdentifier, ExpressionInfo>;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
std::vector<App::ObjectIdentifier> computeEvaluationOrder(ExecuteOption option);
|
||||
|
||||
void buildGraphStructures(const App::ObjectIdentifier &path,
|
||||
const std::shared_ptr<Expression> expression, boost::unordered_map<App::ObjectIdentifier, int> &nodes,
|
||||
boost::unordered_map<int, App::ObjectIdentifier> &revNodes, std::vector<Edge> &edges) const;
|
||||
void buildGraphStructures(const App::ObjectIdentifier& path,
|
||||
const std::shared_ptr<Expression> expression,
|
||||
boost::unordered_map<App::ObjectIdentifier, int>& nodes,
|
||||
boost::unordered_map<int, App::ObjectIdentifier>& revNodes,
|
||||
std::vector<Edge>& edges) const;
|
||||
|
||||
void buildGraph(const ExpressionMap &exprs,
|
||||
boost::unordered_map<int, App::ObjectIdentifier> &revNodes,
|
||||
DiGraph &g, ExecuteOption option=ExecuteAll) const;
|
||||
void buildGraph(const ExpressionMap& exprs,
|
||||
boost::unordered_map<int, App::ObjectIdentifier>& revNodes,
|
||||
DiGraph& g,
|
||||
ExecuteOption option = ExecuteAll) const;
|
||||
|
||||
void slotChangedObject(const App::DocumentObject &obj, const App::Property &prop);
|
||||
void slotChangedProperty(const App::DocumentObject &obj, const App::Property &prop);
|
||||
void updateHiddenReference(const std::string &key);
|
||||
void slotChangedObject(const App::DocumentObject& obj, const App::Property& prop);
|
||||
void slotChangedProperty(const App::DocumentObject& obj, const App::Property& prop);
|
||||
void updateHiddenReference(const std::string& key);
|
||||
|
||||
bool running = false; /**< Boolean used to avoid loops */
|
||||
bool restoring = false;
|
||||
@@ -204,21 +225,22 @@ private:
|
||||
|
||||
ValidatorFunc validator; /**< Valdiator functor */
|
||||
|
||||
struct RestoredExpression {
|
||||
struct RestoredExpression
|
||||
{
|
||||
std::string path;
|
||||
std::string expr;
|
||||
std::string comment;
|
||||
};
|
||||
/**< Expressions are read from file to this map first before they are validated and inserted into the actual map */
|
||||
std::unique_ptr<std::vector<RestoredExpression> > restoredExpressions;
|
||||
/**< Expressions are read from file to this map first before they are validated and inserted
|
||||
* into the actual map */
|
||||
std::unique_ptr<std::vector<RestoredExpression>> restoredExpressions;
|
||||
|
||||
struct Private;
|
||||
std::unique_ptr<Private> pimpl;
|
||||
|
||||
friend class AtomicPropertyChange;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace App
|
||||
|
||||
#endif // EXPRESSIONENGINE_H
|
||||
#endif // EXPRESSIONENGINE_H
|
||||
|
||||
+70
-67
@@ -41,12 +41,11 @@ using namespace Base;
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// PropertyFileIncluded
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
TYPESYSTEM_SOURCE(App::PropertyFileIncluded , App::Property)
|
||||
TYPESYSTEM_SOURCE(App::PropertyFileIncluded, App::Property)
|
||||
|
||||
|
||||
PropertyFileIncluded::PropertyFileIncluded() = default;
|
||||
@@ -78,7 +77,7 @@ void PropertyFileIncluded::aboutToSetValue()
|
||||
std::string PropertyFileIncluded::getDocTransientPath() const
|
||||
{
|
||||
std::string path;
|
||||
PropertyContainer *co = getContainer();
|
||||
PropertyContainer* co = getContainer();
|
||||
if (co->isDerivedFrom(DocumentObject::getClassTypeId())) {
|
||||
path = static_cast<DocumentObject*>(co)->getDocument()->TransientDir.getValue();
|
||||
std::replace(path.begin(), path.end(), '\\', '/');
|
||||
@@ -86,7 +85,8 @@ std::string PropertyFileIncluded::getDocTransientPath() const
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string PropertyFileIncluded::getUniqueFileName(const std::string& path, const std::string& filename) const
|
||||
std::string PropertyFileIncluded::getUniqueFileName(const std::string& path,
|
||||
const std::string& filename) const
|
||||
{
|
||||
Base::Uuid uuid;
|
||||
Base::FileInfo fi(path + "/" + filename);
|
||||
@@ -99,8 +99,8 @@ std::string PropertyFileIncluded::getUniqueFileName(const std::string& path, con
|
||||
|
||||
std::string PropertyFileIncluded::getExchangeTempFile() const
|
||||
{
|
||||
return Base::FileInfo::getTempFileName(Base::FileInfo
|
||||
(getValue()).fileName().c_str(), getDocTransientPath().c_str());
|
||||
return Base::FileInfo::getTempFileName(Base::FileInfo(getValue()).fileName().c_str(),
|
||||
getDocTransientPath().c_str());
|
||||
}
|
||||
|
||||
std::string PropertyFileIncluded::getOriginalFileName() const
|
||||
@@ -111,8 +111,9 @@ std::string PropertyFileIncluded::getOriginalFileName() const
|
||||
void PropertyFileIncluded::setValue(const char* sFile, const char* sName)
|
||||
{
|
||||
if (sFile && sFile[0] != '\0') {
|
||||
if (_cValue == sFile)
|
||||
if (_cValue == sFile) {
|
||||
throw Base::FileSystemError("Not possible to set the same file!");
|
||||
}
|
||||
|
||||
// keep the path to the original file
|
||||
_OriginalName = sFile;
|
||||
@@ -126,7 +127,7 @@ void PropertyFileIncluded::setValue(const char* sFile, const char* sName)
|
||||
throw Base::FileSystemError(str.str());
|
||||
}
|
||||
|
||||
aboutToSetValue(); // undo/redo by moving the file away with temp name
|
||||
aboutToSetValue(); // undo/redo by moving the file away with temp name
|
||||
|
||||
// remove old file (if not moved by undo)
|
||||
Base::FileInfo value(_cValue);
|
||||
@@ -144,16 +145,16 @@ void PropertyFileIncluded::setValue(const char* sFile, const char* sName)
|
||||
std::string dir = pathTrans;
|
||||
std::string fnp = fi.fileNamePure();
|
||||
std::string ext = fi.extension();
|
||||
int i=0;
|
||||
int i = 0;
|
||||
do {
|
||||
i++;
|
||||
std::stringstream str;
|
||||
str << dir << "/" << fnp << i;
|
||||
if (!ext.empty())
|
||||
if (!ext.empty()) {
|
||||
str << "." << ext;
|
||||
}
|
||||
fi.setFile(str.str());
|
||||
}
|
||||
while (fi.exists());
|
||||
} while (fi.exists());
|
||||
|
||||
_cValue = fi.filePath();
|
||||
_BaseFileName = fi.fileName();
|
||||
@@ -189,7 +190,7 @@ void PropertyFileIncluded::setValue(const char* sFile, const char* sName)
|
||||
Base::FileInfo dst(_cValue);
|
||||
dst.setPermissions(Base::FileInfo::ReadOnly);
|
||||
}
|
||||
// otherwise copy from origin location
|
||||
// otherwise copy from origin location
|
||||
else {
|
||||
// if file already exists in transient dir make a new unique name
|
||||
Base::FileInfo fi(_cValue);
|
||||
@@ -198,16 +199,16 @@ void PropertyFileIncluded::setValue(const char* sFile, const char* sName)
|
||||
std::string dir = fi.dirPath();
|
||||
std::string fnp = fi.fileNamePure();
|
||||
std::string ext = fi.extension();
|
||||
int i=0;
|
||||
int i = 0;
|
||||
do {
|
||||
i++;
|
||||
std::stringstream str;
|
||||
str << dir << "/" << fnp << i;
|
||||
if (!ext.empty())
|
||||
if (!ext.empty()) {
|
||||
str << "." << ext;
|
||||
}
|
||||
fi.setFile(str.str());
|
||||
}
|
||||
while (fi.exists());
|
||||
} while (fi.exists());
|
||||
|
||||
_cValue = fi.filePath();
|
||||
_BaseFileName = fi.fileName();
|
||||
@@ -231,40 +232,41 @@ void PropertyFileIncluded::setValue(const char* sFile, const char* sName)
|
||||
|
||||
const char* PropertyFileIncluded::getValue() const
|
||||
{
|
||||
return _cValue.c_str();
|
||||
return _cValue.c_str();
|
||||
}
|
||||
|
||||
PyObject *PropertyFileIncluded::getPyObject()
|
||||
PyObject* PropertyFileIncluded::getPyObject()
|
||||
{
|
||||
PyObject *p = PyUnicode_DecodeUTF8(_cValue.c_str(),_cValue.size(),nullptr);
|
||||
PyObject* p = PyUnicode_DecodeUTF8(_cValue.c_str(), _cValue.size(), nullptr);
|
||||
if (!p) {
|
||||
throw Base::UnicodeError("PropertyFileIncluded: UTF-8 conversion failure");
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
namespace App {
|
||||
namespace App
|
||||
{
|
||||
const char* getNameFromFile(PyObject* value)
|
||||
{
|
||||
const char* string = nullptr;
|
||||
PyObject *oname = PyObject_GetAttrString (value, "name");
|
||||
PyObject* oname = PyObject_GetAttrString(value, "name");
|
||||
if (oname) {
|
||||
if (PyUnicode_Check (oname)) {
|
||||
string = PyUnicode_AsUTF8 (oname);
|
||||
if (PyUnicode_Check(oname)) {
|
||||
string = PyUnicode_AsUTF8(oname);
|
||||
}
|
||||
else if (PyBytes_Check (oname)) {
|
||||
string = PyBytes_AsString (oname);
|
||||
else if (PyBytes_Check(oname)) {
|
||||
string = PyBytes_AsString(oname);
|
||||
}
|
||||
Py_DECREF (oname);
|
||||
Py_DECREF(oname);
|
||||
}
|
||||
|
||||
if (!string)
|
||||
if (!string) {
|
||||
throw Base::TypeError("Unable to get filename");
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool isIOFile(PyObject* file)
|
||||
{
|
||||
PyObject* io = PyImport_ImportModule("io");
|
||||
@@ -274,9 +276,9 @@ bool isIOFile(PyObject* file)
|
||||
Py_DECREF(io);
|
||||
return isFile;
|
||||
}
|
||||
}
|
||||
} // namespace App
|
||||
|
||||
void PropertyFileIncluded::setPyObject(PyObject *value)
|
||||
void PropertyFileIncluded::setPyObject(PyObject* value)
|
||||
{
|
||||
if (PyUnicode_Check(value)) {
|
||||
std::string string = PyUnicode_AsUTF8(value);
|
||||
@@ -286,15 +288,16 @@ void PropertyFileIncluded::setPyObject(PyObject *value)
|
||||
std::string string = PyBytes_AsString(value);
|
||||
setValue(string.c_str());
|
||||
}
|
||||
else if (isIOFile(value)){
|
||||
else if (isIOFile(value)) {
|
||||
std::string string = getNameFromFile(value);
|
||||
setValue(string.c_str());
|
||||
}
|
||||
else if (PyTuple_Check(value)) {
|
||||
if (PyTuple_Size(value) != 2)
|
||||
throw Base::TypeError("Tuple needs size of (filePath,newFileName)");
|
||||
PyObject* file = PyTuple_GetItem(value,0);
|
||||
PyObject* name = PyTuple_GetItem(value,1);
|
||||
if (PyTuple_Size(value) != 2) {
|
||||
throw Base::TypeError("Tuple needs size of (filePath,newFileName)");
|
||||
}
|
||||
PyObject* file = PyTuple_GetItem(value, 0);
|
||||
PyObject* name = PyTuple_GetItem(value, 1);
|
||||
|
||||
// decoding file
|
||||
std::string fileStr;
|
||||
@@ -330,7 +333,7 @@ void PropertyFileIncluded::setPyObject(PyObject *value)
|
||||
throw Base::TypeError(error);
|
||||
}
|
||||
|
||||
setValue(fileStr.c_str(),nameStr.c_str());
|
||||
setValue(fileStr.c_str(), nameStr.c_str());
|
||||
}
|
||||
else if (PyDict_Check(value)) {
|
||||
Py::Dict dict(value);
|
||||
@@ -349,39 +352,40 @@ void PropertyFileIncluded::setPyObject(PyObject *value)
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyFileIncluded::Save (Base::Writer &writer) const
|
||||
void PropertyFileIncluded::Save(Base::Writer& writer) const
|
||||
{
|
||||
// when saving a document under a new file name the transient directory
|
||||
// name changes and thus the stored file name doesn't work any more.
|
||||
if (!_cValue.empty() && !Base::FileInfo(_cValue).exists()) {
|
||||
Base::FileInfo fi(getDocTransientPath() + "/" + _BaseFileName);
|
||||
if (fi.exists())
|
||||
if (fi.exists()) {
|
||||
_cValue = fi.filePath();
|
||||
}
|
||||
}
|
||||
|
||||
if (writer.isForceXML()) {
|
||||
if (!_cValue.empty()) {
|
||||
Base::FileInfo file(_cValue.c_str());
|
||||
writer.Stream() << writer.ind() << "<FileIncluded data=\""
|
||||
<< file.fileName() << "\">" << std::endl;
|
||||
writer.Stream() << writer.ind() << "<FileIncluded data=\"" << file.fileName() << "\">"
|
||||
<< std::endl;
|
||||
// write the file in the XML stream
|
||||
writer.incInd();
|
||||
writer.insertBinFile(_cValue.c_str());
|
||||
writer.decInd();
|
||||
writer.Stream() << writer.ind() <<"</FileIncluded>" << endl;
|
||||
writer.Stream() << writer.ind() << "</FileIncluded>" << endl;
|
||||
}
|
||||
else {
|
||||
writer.Stream() << writer.ind() << "<FileIncluded data=\"\"/>" << std::endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// instead initiate an extra file
|
||||
// instead initiate an extra file
|
||||
if (!_cValue.empty()) {
|
||||
Base::FileInfo file(_cValue.c_str());
|
||||
std::string filename = writer.addFile(file.fileName().c_str(), this);
|
||||
filename = encodeAttribute(filename);
|
||||
writer.Stream() << writer.ind() << "<FileIncluded file=\""
|
||||
<< filename << "\"/>" << std::endl;
|
||||
writer.Stream() << writer.ind() << "<FileIncluded file=\"" << filename << "\"/>"
|
||||
<< std::endl;
|
||||
}
|
||||
else {
|
||||
writer.Stream() << writer.ind() << "<FileIncluded file=\"\"/>" << std::endl;
|
||||
@@ -389,14 +393,14 @@ void PropertyFileIncluded::Save (Base::Writer &writer) const
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyFileIncluded::Restore(Base::XMLReader &reader)
|
||||
void PropertyFileIncluded::Restore(Base::XMLReader& reader)
|
||||
{
|
||||
reader.readElement("FileIncluded");
|
||||
if (reader.hasAttribute("file")) {
|
||||
string file (reader.getAttribute("file") );
|
||||
string file(reader.getAttribute("file"));
|
||||
if (!file.empty()) {
|
||||
// initiate a file read
|
||||
reader.addFile(file.c_str(),this);
|
||||
reader.addFile(file.c_str(), this);
|
||||
// is in the document transient path
|
||||
aboutToSetValue();
|
||||
_cValue = getDocTransientPath() + "/" + file;
|
||||
@@ -406,7 +410,7 @@ void PropertyFileIncluded::Restore(Base::XMLReader &reader)
|
||||
}
|
||||
// section is XML stream
|
||||
else if (reader.hasAttribute("data")) {
|
||||
string file (reader.getAttribute("data") );
|
||||
string file(reader.getAttribute("data"));
|
||||
if (!file.empty()) {
|
||||
// is in the document transient path
|
||||
aboutToSetValue();
|
||||
@@ -422,7 +426,7 @@ void PropertyFileIncluded::Restore(Base::XMLReader &reader)
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyFileIncluded::SaveDocFile (Base::Writer &writer) const
|
||||
void PropertyFileIncluded::SaveDocFile(Base::Writer& writer) const
|
||||
{
|
||||
Base::ifstream from(Base::FileInfo(_cValue.c_str()), std::ios::in | std::ios::binary);
|
||||
if (!from) {
|
||||
@@ -440,7 +444,7 @@ void PropertyFileIncluded::SaveDocFile (Base::Writer &writer) const
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyFileIncluded::RestoreDocFile(Base::Reader &reader)
|
||||
void PropertyFileIncluded::RestoreDocFile(Base::Reader& reader)
|
||||
{
|
||||
Base::FileInfo fi(_cValue.c_str());
|
||||
if (fi.exists() && !fi.isWritable()) {
|
||||
@@ -469,7 +473,7 @@ void PropertyFileIncluded::RestoreDocFile(Base::Reader &reader)
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
Property *PropertyFileIncluded::Copy() const
|
||||
Property* PropertyFileIncluded::Copy() const
|
||||
{
|
||||
std::unique_ptr<PropertyFileIncluded> prop(new PropertyFileIncluded());
|
||||
|
||||
@@ -486,8 +490,8 @@ Property *PropertyFileIncluded::Copy() const
|
||||
if (!done) {
|
||||
std::stringstream str;
|
||||
str << "PropertyFileIncluded::Copy(): "
|
||||
<< "Renaming the file '" << file.filePath() << "' to '"
|
||||
<< newName.filePath() << "' failed.";
|
||||
<< "Renaming the file '" << file.filePath() << "' to '" << newName.filePath()
|
||||
<< "' failed.";
|
||||
throw Base::FileSystemError(str.str());
|
||||
}
|
||||
}
|
||||
@@ -497,14 +501,14 @@ Property *PropertyFileIncluded::Copy() const
|
||||
if (!done) {
|
||||
std::stringstream str;
|
||||
str << "PropertyFileIncluded::Copy(): "
|
||||
<< "Copying the file '" << file.filePath() << "' to '"
|
||||
<< newName.filePath() << "' failed.";
|
||||
<< "Copying the file '" << file.filePath() << "' to '" << newName.filePath()
|
||||
<< "' failed.";
|
||||
throw Base::FileSystemError(str.str());
|
||||
}
|
||||
}
|
||||
|
||||
// remember the new name for the Undo
|
||||
Base::Console().Log("Copy '%s' to '%s'\n",_cValue.c_str(),newName.filePath().c_str());
|
||||
Base::Console().Log("Copy '%s' to '%s'\n", _cValue.c_str(), newName.filePath().c_str());
|
||||
prop->_cValue = newName.filePath().c_str();
|
||||
|
||||
// make backup files writable to avoid copying them again on undo/redo
|
||||
@@ -514,10 +518,10 @@ Property *PropertyFileIncluded::Copy() const
|
||||
return prop.release();
|
||||
}
|
||||
|
||||
void PropertyFileIncluded::Paste(const Property &from)
|
||||
void PropertyFileIncluded::Paste(const Property& from)
|
||||
{
|
||||
aboutToSetValue();
|
||||
const PropertyFileIncluded &prop = dynamic_cast<const PropertyFileIncluded&>(from);
|
||||
const PropertyFileIncluded& prop = dynamic_cast<const PropertyFileIncluded&>(from);
|
||||
// make sure that source and destination file are different
|
||||
if (_cValue != prop._cValue) {
|
||||
// delete old file (if still there)
|
||||
@@ -540,8 +544,8 @@ void PropertyFileIncluded::Paste(const Property &from)
|
||||
if (!fiSrc.renameFile(fiDst.filePath().c_str())) {
|
||||
std::stringstream str;
|
||||
str << "PropertyFileIncluded::Paste(): "
|
||||
<< "Renaming the file '" << fiSrc.filePath() << "' to '"
|
||||
<< fiDst.filePath() << "' failed.";
|
||||
<< "Renaming the file '" << fiSrc.filePath() << "' to '" << fiDst.filePath()
|
||||
<< "' failed.";
|
||||
throw Base::FileSystemError(str.str());
|
||||
}
|
||||
}
|
||||
@@ -549,8 +553,8 @@ void PropertyFileIncluded::Paste(const Property &from)
|
||||
if (!fiSrc.copyTo(fiDst.filePath().c_str())) {
|
||||
std::stringstream str;
|
||||
str << "PropertyFileIncluded::Paste(): "
|
||||
<< "Copying the file '" << fiSrc.filePath() << "' to '"
|
||||
<< fiDst.filePath() << "' failed.";
|
||||
<< "Copying the file '" << fiSrc.filePath() << "' to '" << fiDst.filePath()
|
||||
<< "' failed.";
|
||||
throw Base::FileSystemError(str.str());
|
||||
}
|
||||
}
|
||||
@@ -569,7 +573,7 @@ void PropertyFileIncluded::Paste(const Property &from)
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
unsigned int PropertyFileIncluded::getMemSize () const
|
||||
unsigned int PropertyFileIncluded::getMemSize() const
|
||||
{
|
||||
unsigned int mem = Property::getMemSize();
|
||||
mem += _cValue.size();
|
||||
@@ -591,7 +595,7 @@ std::string PropertyFileIncluded::getFilter() const
|
||||
// PropertyFile
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
TYPESYSTEM_SOURCE(App::PropertyFile , App::PropertyString)
|
||||
TYPESYSTEM_SOURCE(App::PropertyFile, App::PropertyString)
|
||||
|
||||
PropertyFile::PropertyFile()
|
||||
{
|
||||
@@ -610,7 +614,7 @@ std::string PropertyFile::getFilter() const
|
||||
return m_filter;
|
||||
}
|
||||
|
||||
void PropertyFile::setPyObject(PyObject *value)
|
||||
void PropertyFile::setPyObject(PyObject* value)
|
||||
{
|
||||
if (PyDict_Check(value)) {
|
||||
Py::Dict dict(value);
|
||||
@@ -626,4 +630,3 @@ void PropertyFile::setPyObject(PyObject *value)
|
||||
PropertyString::setPyObject(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+49
-39
@@ -29,7 +29,8 @@
|
||||
#include "PropertyStandard.h"
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
class Writer;
|
||||
}
|
||||
|
||||
@@ -37,9 +38,9 @@ namespace App
|
||||
{
|
||||
|
||||
/** File properties
|
||||
* This property holds a file name
|
||||
*/
|
||||
class AppExport PropertyFile : public PropertyString
|
||||
* This property holds a file name
|
||||
*/
|
||||
class AppExport PropertyFile: public PropertyString
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -48,9 +49,11 @@ public:
|
||||
~PropertyFile() override;
|
||||
|
||||
const char* getEditorName() const override
|
||||
{ return "Gui::PropertyEditor::PropertyFileItem"; }
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyFileItem";
|
||||
}
|
||||
|
||||
void setPyObject(PyObject *) override;
|
||||
void setPyObject(PyObject*) override;
|
||||
virtual void setFilter(const std::string filter);
|
||||
virtual std::string getFilter() const;
|
||||
|
||||
@@ -59,20 +62,20 @@ private:
|
||||
};
|
||||
|
||||
/** File include properties
|
||||
* This property doesn't only save the file name like PropertyFile
|
||||
* it also includes the file itself into the document. The file
|
||||
* doesn't get loaded into memory, it gets copied from the document
|
||||
* archive into the document transient directory. There it is accessible for
|
||||
* the algorithms. You get the transient path through getDocTransientPath()
|
||||
* It's allowed to read the file, it's not allowed to write the file
|
||||
* directly in the transient path! That would undermine the Undo/Redo
|
||||
* framework. It's only allowed to use setValue() to change the file.
|
||||
* If you give a file name outside the transient dir to setValue() it
|
||||
* will copy the file. If you give a file name in the transient path it
|
||||
* will just rename and use the same file. You can use getExchangeTempFile() to
|
||||
* get a file name in the transient dir to write a new file version.
|
||||
* This property doesn't only save the file name like PropertyFile
|
||||
* it also includes the file itself into the document. The file
|
||||
* doesn't get loaded into memory, it gets copied from the document
|
||||
* archive into the document transient directory. There it is accessible for
|
||||
* the algorithms. You get the transient path through getDocTransientPath()
|
||||
* It's allowed to read the file, it's not allowed to write the file
|
||||
* directly in the transient path! That would undermine the Undo/Redo
|
||||
* framework. It's only allowed to use setValue() to change the file.
|
||||
* If you give a file name outside the transient dir to setValue() it
|
||||
* will copy the file. If you give a file name in the transient path it
|
||||
* will just rename and use the same file. You can use getExchangeTempFile() to
|
||||
* get a file name in the transient dir to write a new file version.
|
||||
*/
|
||||
class AppExport PropertyFileIncluded : public Property
|
||||
class AppExport PropertyFileIncluded: public Property
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -80,27 +83,31 @@ public:
|
||||
PropertyFileIncluded();
|
||||
~PropertyFileIncluded() override;
|
||||
|
||||
void setValue(const char* sFile, const char* sName=nullptr);
|
||||
void setValue(const char* sFile, const char* sName = nullptr);
|
||||
const char* getValue() const;
|
||||
|
||||
const char* getEditorName() const override
|
||||
{ return "Gui::PropertyEditor::PropertyTransientFileItem"; }
|
||||
PyObject *getPyObject() override;
|
||||
void setPyObject(PyObject *) override;
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyTransientFileItem";
|
||||
}
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject*) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
void SaveDocFile (Base::Writer &writer) const override;
|
||||
void RestoreDocFile(Base::Reader &reader) override;
|
||||
void SaveDocFile(Base::Writer& writer) const override;
|
||||
void RestoreDocFile(Base::Reader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
unsigned int getMemSize () const override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
if (&other == this)
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& _BaseFileName == static_cast<decltype(this)>(&other)->_BaseFileName
|
||||
&& _OriginalName == static_cast<decltype(this)>(&other)->_OriginalName
|
||||
@@ -108,14 +115,17 @@ public:
|
||||
}
|
||||
|
||||
/** get a temp file name in the transient path of the document.
|
||||
* Using this file for new Version of the file and set
|
||||
* this file with setValue() is the fastest way to change
|
||||
* the File.
|
||||
*/
|
||||
* Using this file for new Version of the file and set
|
||||
* this file with setValue() is the fastest way to change
|
||||
* the File.
|
||||
*/
|
||||
std::string getExchangeTempFile() const;
|
||||
std::string getOriginalFileName() const;
|
||||
|
||||
bool isEmpty() const {return _cValue.empty();}
|
||||
bool isEmpty() const
|
||||
{
|
||||
return _cValue.empty();
|
||||
}
|
||||
|
||||
void setFilter(std::string filter);
|
||||
std::string getFilter() const;
|
||||
@@ -136,6 +146,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
} // namespace App
|
||||
} // namespace App
|
||||
|
||||
#endif // APP_PROPERTFILE_H
|
||||
#endif // APP_PROPERTFILE_H
|
||||
|
||||
+293
-245
File diff suppressed because it is too large
Load Diff
+124
-102
@@ -34,11 +34,13 @@
|
||||
#include <FCGlobal.h>
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
class Writer;
|
||||
}
|
||||
|
||||
namespace Data {
|
||||
namespace Data
|
||||
{
|
||||
class ComplexGeoData;
|
||||
}
|
||||
|
||||
@@ -47,7 +49,6 @@ namespace App
|
||||
class Placement;
|
||||
|
||||
|
||||
|
||||
/** Vector properties
|
||||
* This is the father of all properties handling Integers.
|
||||
*/
|
||||
@@ -70,43 +71,48 @@ public:
|
||||
|
||||
/** Sets the property
|
||||
*/
|
||||
void setValue(const Base::Vector3d &vec);
|
||||
void setValue(const Base::Vector3d& vec);
|
||||
void setValue(double x, double y, double z);
|
||||
|
||||
/// Get valid paths for this property; used by auto completer
|
||||
void getPaths(std::vector<ObjectIdentifier> &paths) const override;
|
||||
void getPaths(std::vector<ObjectIdentifier>& paths) const override;
|
||||
|
||||
/** This method returns a string representation of the property
|
||||
*/
|
||||
const Base::Vector3d &getValue() const;
|
||||
const char* getEditorName() const override {
|
||||
const Base::Vector3d& getValue() const;
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyVectorItem";
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
void setPyObject(PyObject *) override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject*) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override {
|
||||
unsigned int getMemSize() const override
|
||||
{
|
||||
return sizeof(Base::Vector3d);
|
||||
}
|
||||
|
||||
const boost::any getPathValue(const ObjectIdentifier &path) const override;
|
||||
const boost::any getPathValue(const ObjectIdentifier& path) const override;
|
||||
|
||||
bool getPyPathValue(const ObjectIdentifier &path, Py::Object &res) const override;
|
||||
bool getPyPathValue(const ObjectIdentifier& path, Py::Object& res) const override;
|
||||
|
||||
virtual Base::Unit getUnit() const {
|
||||
virtual Base::Unit getUnit() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
if (&other == this)
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == dynamic_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
@@ -133,11 +139,13 @@ public:
|
||||
*/
|
||||
~PropertyVectorDistance() override;
|
||||
|
||||
Base::Unit getUnit() const override {
|
||||
Base::Unit getUnit() const override
|
||||
{
|
||||
return Base::Unit::Length;
|
||||
}
|
||||
|
||||
const char* getEditorName() const override {
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyVectorDistanceItem";
|
||||
}
|
||||
};
|
||||
@@ -159,11 +167,13 @@ public:
|
||||
*/
|
||||
~PropertyPosition() override;
|
||||
|
||||
Base::Unit getUnit() const override {
|
||||
Base::Unit getUnit() const override
|
||||
{
|
||||
return Base::Unit::Length;
|
||||
}
|
||||
|
||||
const char* getEditorName() const override {
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyPositionItem";
|
||||
}
|
||||
};
|
||||
@@ -185,11 +195,13 @@ public:
|
||||
*/
|
||||
~PropertyDirection() override;
|
||||
|
||||
Base::Unit getUnit() const override {
|
||||
Base::Unit getUnit() const override
|
||||
{
|
||||
return Base::Unit::Length;
|
||||
}
|
||||
|
||||
const char* getEditorName() const override {
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyDirectionItem";
|
||||
}
|
||||
};
|
||||
@@ -216,24 +228,25 @@ public:
|
||||
void setValue(double x, double y, double z);
|
||||
using inherited::setValue;
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
void SaveDocFile (Base::Writer &writer) const override;
|
||||
void RestoreDocFile(Base::Reader &reader) override;
|
||||
void SaveDocFile(Base::Writer& writer) const override;
|
||||
void RestoreDocFile(Base::Reader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override;
|
||||
const char* getEditorName() const override {
|
||||
unsigned int getMemSize() const override;
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyVectorListItem";
|
||||
}
|
||||
|
||||
protected:
|
||||
Base::Vector3d getPyValue(PyObject *) const override;
|
||||
Base::Vector3d getPyValue(PyObject*) const override;
|
||||
};
|
||||
|
||||
/// Property representing a 4x4 matrix
|
||||
@@ -259,31 +272,35 @@ public:
|
||||
|
||||
/** Sets the property
|
||||
*/
|
||||
void setValue(const Base::Matrix4D &mat);
|
||||
void setValue(const Base::Matrix4D& mat);
|
||||
|
||||
/** This method returns a string representation of the property
|
||||
*/
|
||||
const Base::Matrix4D &getValue() const;
|
||||
const char* getEditorName() const override {
|
||||
const Base::Matrix4D& getValue() const;
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyMatrixItem";
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
void setPyObject(PyObject *) override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject*) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override {
|
||||
unsigned int getMemSize() const override
|
||||
{
|
||||
return sizeof(Base::Matrix4D);
|
||||
}
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
if (&other == this)
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
@@ -315,49 +332,52 @@ public:
|
||||
|
||||
/** Sets the property
|
||||
*/
|
||||
void setValue(const Base::Placement &pos);
|
||||
void setValue(const Base::Placement& pos);
|
||||
|
||||
/** Sets property only if changed
|
||||
* @param pos: input placement
|
||||
* @param tol: position tolerance
|
||||
* @param atol: angular tolerance
|
||||
*/
|
||||
bool setValueIfChanged(const Base::Placement &pos,
|
||||
double tol=1e-7, double atol=1e-12);
|
||||
bool setValueIfChanged(const Base::Placement& pos, double tol = 1e-7, double atol = 1e-12);
|
||||
|
||||
/** This method returns a string representation of the property
|
||||
*/
|
||||
const Base::Placement &getValue() const;
|
||||
const Base::Placement& getValue() const;
|
||||
|
||||
/// Get valid paths for this property; used by auto completer
|
||||
void getPaths(std::vector<ObjectIdentifier> &paths) const override;
|
||||
void getPaths(std::vector<ObjectIdentifier>& paths) const override;
|
||||
|
||||
void setPathValue(const ObjectIdentifier &path, const boost::any &value) override;
|
||||
void setPathValue(const ObjectIdentifier& path, const boost::any& value) override;
|
||||
|
||||
const boost::any getPathValue(const ObjectIdentifier &path) const override;
|
||||
const boost::any getPathValue(const ObjectIdentifier& path) const override;
|
||||
|
||||
bool getPyPathValue(const ObjectIdentifier &path, Py::Object &res) const override;
|
||||
bool getPyPathValue(const ObjectIdentifier& path, Py::Object& res) const override;
|
||||
|
||||
const char* getEditorName() const override {
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyPlacementItem";
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
void setPyObject(PyObject *) override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject*) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override {
|
||||
unsigned int getMemSize() const override
|
||||
{
|
||||
return sizeof(Base::Placement);
|
||||
}
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
if (&other == this)
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
@@ -371,7 +391,7 @@ private:
|
||||
/** the general Link Property
|
||||
* Main Purpose of this property is to Link Objects and Features in a document.
|
||||
*/
|
||||
class AppExport PropertyPlacementLink : public PropertyLink
|
||||
class AppExport PropertyPlacementLink: public PropertyLink
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -390,10 +410,10 @@ public:
|
||||
|
||||
/** This method returns the linked DocumentObject
|
||||
*/
|
||||
App::Placement * getPlacementObject() const;
|
||||
App::Placement* getPlacementObject() const;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
};
|
||||
|
||||
|
||||
@@ -409,21 +429,21 @@ public:
|
||||
|
||||
~PropertyPlacementList() override;
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
void SaveDocFile (Base::Writer &writer) const override;
|
||||
void RestoreDocFile(Base::Reader &reader) override;
|
||||
void SaveDocFile(Base::Writer& writer) const override;
|
||||
void RestoreDocFile(Base::Reader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
protected:
|
||||
Base::Placement getPyValue(PyObject *) const override;
|
||||
Base::Placement getPyValue(PyObject* item) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -431,7 +451,7 @@ protected:
|
||||
/*!
|
||||
* Encapsulates a Base::Rotation in a Property
|
||||
*/
|
||||
class AppExport PropertyRotation : public Property
|
||||
class AppExport PropertyRotation: public Property
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -450,42 +470,44 @@ public:
|
||||
|
||||
/** Sets the property
|
||||
*/
|
||||
void setValue(const Base::Rotation &rot);
|
||||
void setValue(const Base::Rotation& rot);
|
||||
|
||||
/** Sets property only if changed
|
||||
* @param pos: input placement
|
||||
* @param tol: position tolerance
|
||||
* @param atol: angular tolerance
|
||||
*/
|
||||
bool setValueIfChanged(const Base::Rotation &rot, double atol=1e-12);
|
||||
bool setValueIfChanged(const Base::Rotation& rot, double atol = 1e-12);
|
||||
|
||||
/** This method returns a string representation of the property
|
||||
*/
|
||||
const Base::Rotation &getValue() const;
|
||||
const Base::Rotation& getValue() const;
|
||||
|
||||
/// Get valid paths for this property; used by auto completer
|
||||
void getPaths(std::vector<ObjectIdentifier> &paths) const override;
|
||||
void getPaths(std::vector<ObjectIdentifier>& paths) const override;
|
||||
|
||||
void setPathValue(const ObjectIdentifier &path, const boost::any &value) override;
|
||||
void setPathValue(const ObjectIdentifier& path, const boost::any& value) override;
|
||||
|
||||
const boost::any getPathValue(const ObjectIdentifier &path) const override;
|
||||
const boost::any getPathValue(const ObjectIdentifier& path) const override;
|
||||
|
||||
bool getPyPathValue(const ObjectIdentifier &path, Py::Object &res) const override;
|
||||
bool getPyPathValue(const ObjectIdentifier& path, Py::Object& res) const override;
|
||||
|
||||
const char* getEditorName() const override {
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyRotationItem";
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
void setPyObject(PyObject *) override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject*) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override {
|
||||
unsigned int getMemSize() const override
|
||||
{
|
||||
return sizeof(Base::Placement);
|
||||
}
|
||||
|
||||
@@ -497,7 +519,7 @@ private:
|
||||
/** The base class for all basic geometry properties.
|
||||
* @author Werner Mayer
|
||||
*/
|
||||
class AppExport PropertyGeometry : public App::Property
|
||||
class AppExport PropertyGeometry: public App::Property
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -512,7 +534,7 @@ public:
|
||||
/// Get the placement of the geometry
|
||||
virtual Base::Matrix4D getTransform() const = 0;
|
||||
/// Applies a transformation on the real geometric data type
|
||||
virtual void transformGeometry(const Base::Matrix4D &rclMat) = 0;
|
||||
virtual void transformGeometry(const Base::Matrix4D& rclMat) = 0;
|
||||
/// Retrieve bounding box information
|
||||
virtual Base::BoundBox3d getBoundingBox() const = 0;
|
||||
//@}
|
||||
@@ -521,7 +543,7 @@ public:
|
||||
/** The base class for all complex data properties.
|
||||
* @author Werner Mayer
|
||||
*/
|
||||
class AppExport PropertyComplexGeoData : public App::PropertyGeometry
|
||||
class AppExport PropertyComplexGeoData: public App::PropertyGeometry
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -532,7 +554,7 @@ public:
|
||||
/** @name Modification */
|
||||
//@{
|
||||
/// Applies a transformation on the real geometric data type
|
||||
void transformGeometry(const Base::Matrix4D &rclMat) override = 0;
|
||||
void transformGeometry(const Base::Matrix4D& rclMat) override = 0;
|
||||
//@}
|
||||
|
||||
/** @name Getting basic geometric entities */
|
||||
@@ -546,15 +568,15 @@ public:
|
||||
* @param persisted: if true, return the restored element map version. Or
|
||||
* else, return the current element map version
|
||||
*/
|
||||
virtual std::string getElementMapVersion(bool restored=false) const;
|
||||
virtual std::string getElementMapVersion(bool restored = false) const;
|
||||
|
||||
/// Return true to signal element map version change
|
||||
virtual bool checkElementMapVersion(const char * ver) const;
|
||||
virtual bool checkElementMapVersion(const char* ver) const;
|
||||
|
||||
void afterRestore() override;
|
||||
};
|
||||
|
||||
} // namespace App
|
||||
} // namespace App
|
||||
|
||||
|
||||
#endif // APP_PROPERTYGEO_H
|
||||
#endif // APP_PROPERTYGEO_H
|
||||
|
||||
+2356
-1674
File diff suppressed because it is too large
Load Diff
+591
-403
File diff suppressed because it is too large
Load Diff
@@ -39,7 +39,7 @@
|
||||
using namespace App;
|
||||
|
||||
|
||||
TYPESYSTEM_SOURCE(App::PropertyPythonObject , App::Property)
|
||||
TYPESYSTEM_SOURCE(App::PropertyPythonObject, App::Property)
|
||||
|
||||
PropertyPythonObject::PropertyPythonObject() = default;
|
||||
|
||||
@@ -51,11 +51,11 @@ PropertyPythonObject::~PropertyPythonObject()
|
||||
this->object = Py::Object();
|
||||
}
|
||||
|
||||
void PropertyPythonObject::setValue(Py::Object o)
|
||||
void PropertyPythonObject::setValue(const Py::Object& py)
|
||||
{
|
||||
Base::PyGILStateLocker lock;
|
||||
aboutToSetValue();
|
||||
this->object = o;
|
||||
this->object = py;
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
@@ -64,12 +64,12 @@ Py::Object PropertyPythonObject::getValue() const
|
||||
return object;
|
||||
}
|
||||
|
||||
PyObject *PropertyPythonObject::getPyObject()
|
||||
PyObject* PropertyPythonObject::getPyObject()
|
||||
{
|
||||
return Py::new_reference_to(this->object);
|
||||
}
|
||||
|
||||
void PropertyPythonObject::setPyObject(PyObject * obj)
|
||||
void PropertyPythonObject::setPyObject(PyObject* obj)
|
||||
{
|
||||
Base::PyGILStateLocker lock;
|
||||
aboutToSetValue();
|
||||
@@ -82,9 +82,10 @@ std::string PropertyPythonObject::toString() const
|
||||
std::string repr;
|
||||
Base::PyGILStateLocker lock;
|
||||
try {
|
||||
Py::Module pickle(PyImport_ImportModule("json"),true);
|
||||
if (pickle.isNull())
|
||||
Py::Module pickle(PyImport_ImportModule("json"), true);
|
||||
if (pickle.isNull()) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
Py::Callable method(pickle.getAttr(std::string("dumps")));
|
||||
Py::Object dump;
|
||||
if (this->object.hasAttr("dumps")) {
|
||||
@@ -95,10 +96,9 @@ std::string PropertyPythonObject::toString() const
|
||||
// support add-ons that use the old method names
|
||||
else if (this->object.hasAttr("__getstate__")
|
||||
#if PY_VERSION_HEX >= 0x030b0000
|
||||
&& this->object.getAttr("__getstate__").hasAttr("__func__")
|
||||
&& this->object.getAttr("__getstate__").hasAttr("__func__")
|
||||
#endif
|
||||
)
|
||||
{
|
||||
) {
|
||||
Py::Tuple args;
|
||||
Py::Callable state(this->object.getAttr("__getstate__"));
|
||||
dump = state.apply(args);
|
||||
@@ -118,8 +118,9 @@ std::string PropertyPythonObject::toString() const
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
Py::String typestr(this->object.type().str());
|
||||
Base::Console().Error("PropertyPythonObject::toString(): failed for %s\n", typestr.as_string().c_str());
|
||||
Base::PyException e; // extract the Python error text
|
||||
Base::Console().Error("PropertyPythonObject::toString(): failed for %s\n",
|
||||
typestr.as_string().c_str());
|
||||
Base::PyException e; // extract the Python error text
|
||||
e.ReportException();
|
||||
}
|
||||
|
||||
@@ -130,11 +131,13 @@ void PropertyPythonObject::fromString(const std::string& repr)
|
||||
{
|
||||
Base::PyGILStateLocker lock;
|
||||
try {
|
||||
if (repr.empty())
|
||||
if (repr.empty()) {
|
||||
return;
|
||||
Py::Module pickle(PyImport_ImportModule("json"),true);
|
||||
if (pickle.isNull())
|
||||
}
|
||||
Py::Module pickle(PyImport_ImportModule("json"), true);
|
||||
if (pickle.isNull()) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
Py::Callable method(pickle.getAttr(std::string("loads")));
|
||||
Py::Tuple args(1);
|
||||
args.setItem(0, Py::String(repr));
|
||||
@@ -149,10 +152,9 @@ void PropertyPythonObject::fromString(const std::string& repr)
|
||||
// support add-ons that use the old method names
|
||||
else if (this->object.hasAttr("__setstate__")
|
||||
#if PY_VERSION_HEX >= 0x030b0000
|
||||
&& this->object.getAttr("__setstate__").hasAttr("__func__")
|
||||
&& this->object.getAttr("__setstate__").hasAttr("__func__")
|
||||
#endif
|
||||
)
|
||||
{
|
||||
) {
|
||||
Py::Tuple args(1);
|
||||
args.setItem(0, res);
|
||||
Py::Callable state(this->object.getAttr("__setstate__"));
|
||||
@@ -168,7 +170,7 @@ void PropertyPythonObject::fromString(const std::string& repr)
|
||||
}
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
Base::PyException e; // extract the Python error text
|
||||
Base::PyException e; // extract the Python error text
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
@@ -194,7 +196,7 @@ void PropertyPythonObject::loadPickle(const std::string& str)
|
||||
}
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
Base::PyException e; // extract the Python error text
|
||||
Base::PyException e; // extract the Python error text
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
@@ -203,18 +205,24 @@ std::string PropertyPythonObject::encodeValue(const std::string& str) const
|
||||
{
|
||||
std::string tmp;
|
||||
for (char it : str) {
|
||||
if (it == '<')
|
||||
if (it == '<') {
|
||||
tmp += "<";
|
||||
else if (it == '"')
|
||||
}
|
||||
else if (it == '"') {
|
||||
tmp += """;
|
||||
else if (it == '&')
|
||||
}
|
||||
else if (it == '&') {
|
||||
tmp += "&";
|
||||
else if (it == '>')
|
||||
}
|
||||
else if (it == '>') {
|
||||
tmp += ">";
|
||||
else if (it == '\n')
|
||||
}
|
||||
else if (it == '\n') {
|
||||
tmp += "\\n";
|
||||
else
|
||||
}
|
||||
else {
|
||||
tmp += it;
|
||||
}
|
||||
}
|
||||
|
||||
return tmp;
|
||||
@@ -230,14 +238,15 @@ std::string PropertyPythonObject::decodeValue(const std::string& str) const
|
||||
tmp += '\n';
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
tmp += *it;
|
||||
}
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void PropertyPythonObject::saveObject(Base::Writer &writer) const
|
||||
void PropertyPythonObject::saveObject(Base::Writer& writer) const
|
||||
{
|
||||
Base::PyGILStateLocker lock;
|
||||
try {
|
||||
@@ -258,19 +267,19 @@ void PropertyPythonObject::saveObject(Base::Writer &writer) const
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyPythonObject::restoreObject(Base::XMLReader &reader)
|
||||
void PropertyPythonObject::restoreObject(Base::XMLReader& reader)
|
||||
{
|
||||
Base::PyGILStateLocker lock;
|
||||
try {
|
||||
PropertyContainer* parent = this->getContainer();
|
||||
if (reader.hasAttribute("object")) {
|
||||
if (strcmp(reader.getAttribute("object"),"yes") == 0) {
|
||||
if (strcmp(reader.getAttribute("object"), "yes") == 0) {
|
||||
Py::Object obj = Py::asObject(parent->getPyObject());
|
||||
this->object.setAttr("__object__", obj);
|
||||
}
|
||||
}
|
||||
if (reader.hasAttribute("vobject")) {
|
||||
if (strcmp(reader.getAttribute("vobject"),"yes") == 0) {
|
||||
if (strcmp(reader.getAttribute("vobject"), "yes") == 0) {
|
||||
Py::Object obj = Py::asObject(parent->getPyObject());
|
||||
this->object.setAttr("__vobject__", obj);
|
||||
}
|
||||
@@ -280,65 +289,57 @@ void PropertyPythonObject::restoreObject(Base::XMLReader &reader)
|
||||
e.clear();
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Error("%s\n",e.what());
|
||||
Base::Console().Error("%s\n", e.what());
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Error("Critical error in PropertyPythonObject::restoreObject\n");
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyPythonObject::Save (Base::Writer &writer) const
|
||||
void PropertyPythonObject::Save(Base::Writer& writer) const
|
||||
{
|
||||
//if (writer.isForceXML()) {
|
||||
std::string repr = this->toString();
|
||||
repr = Base::base64_encode((const unsigned char*)repr.c_str(), repr.size());
|
||||
std::string val = /*encodeValue*/(repr);
|
||||
writer.Stream() << writer.ind() << "<Python value=\"" << val
|
||||
<< R"(" encoded="yes")";
|
||||
std::string repr = this->toString();
|
||||
repr = Base::base64_encode((const unsigned char*)repr.c_str(), repr.size());
|
||||
std::string val = /*encodeValue*/ (repr);
|
||||
writer.Stream() << writer.ind() << "<Python value=\"" << val << R"(" encoded="yes")";
|
||||
|
||||
Base::PyGILStateLocker lock;
|
||||
try {
|
||||
if (this->object.hasAttr("__module__") && this->object.hasAttr("__class__")) {
|
||||
Py::String mod(this->object.getAttr("__module__"));
|
||||
Py::Object cls(this->object.getAttr("__class__"));
|
||||
if (cls.hasAttr("__name__")) {
|
||||
Py::String name(cls.getAttr("__name__"));
|
||||
writer.Stream() << " module=\"" << (std::string)mod << "\""
|
||||
<< " class=\"" << (std::string)name << "\"";
|
||||
}
|
||||
}
|
||||
else {
|
||||
writer.Stream() << " json=\"yes\"";
|
||||
Base::PyGILStateLocker lock;
|
||||
try {
|
||||
if (this->object.hasAttr("__module__") && this->object.hasAttr("__class__")) {
|
||||
Py::String mod(this->object.getAttr("__module__"));
|
||||
Py::Object cls(this->object.getAttr("__class__"));
|
||||
if (cls.hasAttr("__name__")) {
|
||||
Py::String name(cls.getAttr("__name__"));
|
||||
writer.Stream() << " module=\"" << (std::string)mod << "\""
|
||||
<< " class=\"" << (std::string)name << "\"";
|
||||
}
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
Base::PyException e; // extract the Python error text
|
||||
e.ReportException();
|
||||
else {
|
||||
writer.Stream() << " json=\"yes\"";
|
||||
}
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
Base::PyException e; // extract the Python error text
|
||||
e.ReportException();
|
||||
}
|
||||
|
||||
saveObject(writer);
|
||||
writer.Stream() << "/>" << std::endl;
|
||||
//}
|
||||
//else {
|
||||
// writer.Stream() << writer.ind() << "<Python file=\"" <<
|
||||
// writer.addFile("pickle", this) << "\"/>" << std::endl;
|
||||
//}
|
||||
saveObject(writer);
|
||||
writer.Stream() << "/>" << std::endl;
|
||||
}
|
||||
|
||||
void PropertyPythonObject::Restore(Base::XMLReader &reader)
|
||||
void PropertyPythonObject::Restore(Base::XMLReader& reader)
|
||||
{
|
||||
reader.readElement("Python");
|
||||
if (reader.hasAttribute("file")) {
|
||||
std::string file(reader.getAttribute("file"));
|
||||
reader.addFile(file.c_str(),this);
|
||||
reader.addFile(file.c_str(), this);
|
||||
}
|
||||
else {
|
||||
bool load_json=false;
|
||||
bool load_pickle=false;
|
||||
bool load_failed=false;
|
||||
bool load_json = false;
|
||||
bool load_pickle = false;
|
||||
bool load_failed = false;
|
||||
std::string buffer = reader.getAttribute("value");
|
||||
if (reader.hasAttribute("encoded") &&
|
||||
strcmp(reader.getAttribute("encoded"),"yes") == 0) {
|
||||
if (reader.hasAttribute("encoded") && strcmp(reader.getAttribute("encoded"), "yes") == 0) {
|
||||
buffer = Base::base64_decode(buffer);
|
||||
}
|
||||
else {
|
||||
@@ -353,14 +354,15 @@ void PropertyPythonObject::Restore(Base::XMLReader &reader)
|
||||
start = buffer.begin();
|
||||
end = buffer.end();
|
||||
if (reader.hasAttribute("module") && reader.hasAttribute("class")) {
|
||||
Py::Module mod(PyImport_ImportModule(reader.getAttribute("module")),true);
|
||||
if (mod.isNull())
|
||||
Py::Module mod(PyImport_ImportModule(reader.getAttribute("module")), true);
|
||||
if (mod.isNull()) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
PyObject* cls = mod.getAttr(reader.getAttribute("class")).ptr();
|
||||
if (!cls) {
|
||||
std::stringstream s;
|
||||
s << "Module " << reader.getAttribute("module")
|
||||
<< " has no class " << reader.getAttribute("class");
|
||||
s << "Module " << reader.getAttribute("module") << " has no class "
|
||||
<< reader.getAttribute("class");
|
||||
throw Py::AttributeError(s.str());
|
||||
}
|
||||
if (PyType_Check(cls)) {
|
||||
@@ -374,9 +376,10 @@ void PropertyPythonObject::Restore(Base::XMLReader &reader)
|
||||
else if (boost::regex_search(start, end, what, pickle)) {
|
||||
std::string name = std::string(what[1].first, what[1].second);
|
||||
std::string type = std::string(what[2].first, what[2].second);
|
||||
Py::Module mod(PyImport_ImportModule(name.c_str()),true);
|
||||
if (mod.isNull())
|
||||
Py::Module mod(PyImport_ImportModule(name.c_str()), true);
|
||||
if (mod.isNull()) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
this->object = PyObject_CallObject(mod.getAttr(type).ptr(), nullptr);
|
||||
load_pickle = true;
|
||||
buffer = std::string(what[2].second, end);
|
||||
@@ -386,57 +389,63 @@ void PropertyPythonObject::Restore(Base::XMLReader &reader)
|
||||
}
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
Base::PyException e; // extract the Python error text
|
||||
Base::PyException e; // extract the Python error text
|
||||
e.ReportException();
|
||||
this->object = Py::None();
|
||||
load_failed = true;
|
||||
}
|
||||
|
||||
aboutToSetValue();
|
||||
if (load_json)
|
||||
if (load_json) {
|
||||
this->fromString(buffer);
|
||||
else if (load_pickle)
|
||||
}
|
||||
else if (load_pickle) {
|
||||
this->loadPickle(buffer);
|
||||
else if (!load_failed)
|
||||
Base::Console().Warning("PropertyPythonObject::Restore: unsupported serialisation: %s\n", buffer.c_str());
|
||||
}
|
||||
else if (!load_failed) {
|
||||
Base::Console().Warning(
|
||||
"PropertyPythonObject::Restore: unsupported serialisation: %s\n",
|
||||
buffer.c_str());
|
||||
}
|
||||
restoreObject(reader);
|
||||
hasSetValue();
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyPythonObject::SaveDocFile (Base::Writer &writer) const
|
||||
void PropertyPythonObject::SaveDocFile(Base::Writer& writer) const
|
||||
{
|
||||
std::string buffer = this->toString();
|
||||
for (char it : buffer)
|
||||
for (char it : buffer) {
|
||||
writer.Stream().put(it);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyPythonObject::RestoreDocFile(Base::Reader &reader)
|
||||
void PropertyPythonObject::RestoreDocFile(Base::Reader& reader)
|
||||
{
|
||||
aboutToSetValue();
|
||||
std::string buffer;
|
||||
char c;
|
||||
while (reader.get(c)) {
|
||||
buffer.push_back(c);
|
||||
char ch {};
|
||||
while (reader.get(ch)) {
|
||||
buffer.push_back(ch);
|
||||
}
|
||||
this->fromString(buffer);
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
unsigned int PropertyPythonObject::getMemSize () const
|
||||
unsigned int PropertyPythonObject::getMemSize() const
|
||||
{
|
||||
return sizeof(Py::Object);
|
||||
}
|
||||
|
||||
Property *PropertyPythonObject::Copy() const
|
||||
Property* PropertyPythonObject::Copy() const
|
||||
{
|
||||
PropertyPythonObject *p = new PropertyPythonObject();
|
||||
PropertyPythonObject* p = new PropertyPythonObject();
|
||||
Base::PyGILStateLocker lock;
|
||||
p->object = this->object;
|
||||
return p;
|
||||
}
|
||||
|
||||
void PropertyPythonObject::Paste(const Property &from)
|
||||
void PropertyPythonObject::Paste(const Property& from)
|
||||
{
|
||||
if (from.is<PropertyPythonObject>()) {
|
||||
Base::PyGILStateLocker lock;
|
||||
|
||||
@@ -30,10 +30,11 @@
|
||||
#include "Property.h"
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
class Writer;
|
||||
class XMLReader;
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
namespace App
|
||||
{
|
||||
@@ -42,7 +43,7 @@ namespace App
|
||||
* PropertyPythonObject is used to manage Py::Object instances as properties.
|
||||
* @author Werner Mayer
|
||||
*/
|
||||
class AppExport PropertyPythonObject : public Property
|
||||
class AppExport PropertyPythonObject: public Property
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -50,29 +51,29 @@ public:
|
||||
PropertyPythonObject();
|
||||
~PropertyPythonObject() override;
|
||||
|
||||
void setValue(Py::Object);
|
||||
void setValue(const Py::Object& py);
|
||||
Py::Object getValue() const;
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
void setPyObject(PyObject *) override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject* obj) override;
|
||||
|
||||
/** Use Python's pickle module to save the object */
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
/** Use Python's pickle module to restore the object */
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void SaveDocFile (Base::Writer &writer) const override;
|
||||
void RestoreDocFile(Base::Reader &reader) override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
void SaveDocFile(Base::Writer& writer) const override;
|
||||
void RestoreDocFile(Base::Reader& reader) override;
|
||||
|
||||
unsigned int getMemSize () const override;
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
unsigned int getMemSize() const override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
std::string toString() const;
|
||||
void fromString(const std::string&);
|
||||
|
||||
private:
|
||||
void saveObject(Base::Writer &writer) const;
|
||||
void restoreObject(Base::XMLReader &reader);
|
||||
void saveObject(Base::Writer& writer) const;
|
||||
void restoreObject(Base::XMLReader& reader);
|
||||
std::string encodeValue(const std::string& str) const;
|
||||
std::string decodeValue(const std::string& str) const;
|
||||
void loadPickle(const std::string& str);
|
||||
@@ -80,6 +81,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
} // namespace App
|
||||
} // namespace App
|
||||
|
||||
#endif // APP_PROPERTYPYTHONOBJECT_H
|
||||
#endif // APP_PROPERTYPYTHONOBJECT_H
|
||||
|
||||
+634
-493
File diff suppressed because it is too large
Load Diff
+294
-208
@@ -37,11 +37,12 @@
|
||||
#include "Material.h"
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
class InputStream;
|
||||
class OutputStream;
|
||||
class Writer;
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
|
||||
namespace App
|
||||
@@ -65,23 +66,33 @@ public:
|
||||
/** This method returns a string representation of the property
|
||||
*/
|
||||
long getValue() const;
|
||||
const char* getEditorName() const override { return "Gui::PropertyEditor::PropertyIntegerItem"; }
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyIntegerItem";
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override{return sizeof(long);}
|
||||
unsigned int getMemSize() const override
|
||||
{
|
||||
return sizeof(long);
|
||||
}
|
||||
|
||||
void setPathValue(const App::ObjectIdentifier & path, const boost::any & value) override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier & /*path*/) const override { return _lValue; }
|
||||
void setPathValue(const App::ObjectIdentifier& path, const boost::any& value) override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier& /*path*/) const override
|
||||
{
|
||||
return _lValue;
|
||||
}
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
@@ -101,36 +112,39 @@ class AppExport PropertyPath: public Property
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
|
||||
PropertyPath();
|
||||
~PropertyPath() override;
|
||||
|
||||
/** Sets the property
|
||||
*/
|
||||
void setValue(const boost::filesystem::path &);
|
||||
void setValue(const boost::filesystem::path&);
|
||||
|
||||
/** Sets the property
|
||||
*/
|
||||
void setValue(const char *);
|
||||
void setValue(const char*);
|
||||
|
||||
/** This method returns a string representation of the property
|
||||
*/
|
||||
const boost::filesystem::path &getValue() const;
|
||||
const boost::filesystem::path& getValue() const;
|
||||
|
||||
const char* getEditorName() const override { return "Gui::PropertyEditor::PropertyPathItem"; }
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyPathItem";
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
@@ -152,7 +166,7 @@ public:
|
||||
PropertyEnumeration();
|
||||
|
||||
/// Obvious constructor
|
||||
explicit PropertyEnumeration(const Enumeration &e);
|
||||
explicit PropertyEnumeration(const Enumeration& e);
|
||||
|
||||
/// destructor
|
||||
~PropertyEnumeration() override;
|
||||
@@ -173,7 +187,7 @@ public:
|
||||
/** setting the enumeration string as vector of strings
|
||||
* This makes the enumeration custom.
|
||||
*/
|
||||
void setEnums(const std::vector<std::string> &Enums);
|
||||
void setEnums(const std::vector<std::string>& Enums);
|
||||
|
||||
/** set the enum by a string
|
||||
* is slower than setValue(long). Use long if possible
|
||||
@@ -187,7 +201,7 @@ public:
|
||||
void setValue(long);
|
||||
|
||||
/// Setter using Enumeration
|
||||
void setValue(const Enumeration &source);
|
||||
void setValue(const Enumeration& source);
|
||||
|
||||
/// Returns current value of the enumeration as an integer
|
||||
long getValue() const;
|
||||
@@ -199,16 +213,16 @@ public:
|
||||
bool isPartOf(const char* value) const;
|
||||
|
||||
/// get the value as string
|
||||
const char * getValueAsString() const;
|
||||
const char* getValueAsString() const;
|
||||
|
||||
/// Returns Enumeration object
|
||||
const Enumeration &getEnum() const;
|
||||
const Enumeration& getEnum() const;
|
||||
|
||||
/// get all possible enum values as vector of strings
|
||||
std::vector<std::string> getEnumVector() const;
|
||||
|
||||
/// set enum values as vector of strings
|
||||
void setEnumVector(const std::vector<std::string> &);
|
||||
void setEnumVector(const std::vector<std::string>&);
|
||||
/// get the pointer to the enum list
|
||||
bool hasEnums() const;
|
||||
|
||||
@@ -216,24 +230,31 @@ public:
|
||||
bool isValid() const;
|
||||
//@}
|
||||
|
||||
const char* getEditorName() const override { return _editorTypeName.c_str(); }
|
||||
void setEditorName(const char* name) { _editorTypeName = name; }
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return _editorTypeName.c_str();
|
||||
}
|
||||
void setEditorName(const char* name)
|
||||
{
|
||||
_editorTypeName = name;
|
||||
}
|
||||
|
||||
PyObject * getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
void Save(Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property * Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
void setPathValue(const App::ObjectIdentifier & path, const boost::any & value) override;
|
||||
virtual bool setPyPathValue(const App::ObjectIdentifier & path, const Py::Object &value);
|
||||
const boost::any getPathValue(const App::ObjectIdentifier & /*path*/) const override;
|
||||
bool getPyPathValue(const ObjectIdentifier &path, Py::Object &r) const override;
|
||||
void setPathValue(const App::ObjectIdentifier& path, const boost::any& value) override;
|
||||
virtual bool setPyPathValue(const App::ObjectIdentifier& path, const Py::Object& value);
|
||||
const boost::any getPathValue(const App::ObjectIdentifier& /*path*/) const override;
|
||||
bool getPyPathValue(const ObjectIdentifier& path, Py::Object& r) const override;
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
@@ -266,22 +287,21 @@ public:
|
||||
/// Constraint methods
|
||||
//@{
|
||||
/// the boundary struct
|
||||
struct Constraints {
|
||||
struct Constraints
|
||||
{
|
||||
long LowerBound, UpperBound, StepSize;
|
||||
Constraints()
|
||||
: LowerBound(0)
|
||||
, UpperBound(0)
|
||||
, StepSize(0)
|
||||
, candelete(false)
|
||||
{
|
||||
}
|
||||
{}
|
||||
Constraints(long l, long u, long s)
|
||||
: LowerBound(l)
|
||||
, UpperBound(u)
|
||||
, StepSize(s)
|
||||
, candelete(false)
|
||||
{
|
||||
}
|
||||
{}
|
||||
~Constraints() = default;
|
||||
void setDeletable(bool on)
|
||||
{
|
||||
@@ -291,6 +311,7 @@ public:
|
||||
{
|
||||
return candelete;
|
||||
}
|
||||
|
||||
private:
|
||||
bool candelete;
|
||||
};
|
||||
@@ -304,18 +325,21 @@ public:
|
||||
*/
|
||||
void setConstraints(const Constraints* sConstraint);
|
||||
/// get the constraint struct
|
||||
const Constraints* getConstraints() const;
|
||||
const Constraints* getConstraints() const;
|
||||
//@}
|
||||
|
||||
long getMinimum() const;
|
||||
long getMaximum() const;
|
||||
long getStepSize() const;
|
||||
|
||||
const char* getEditorName() const override { return "Gui::PropertyEditor::PropertyIntegerConstraintItem"; }
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyIntegerConstraintItem";
|
||||
}
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
protected:
|
||||
const Constraints* _ConstStruct{nullptr};
|
||||
const Constraints* _ConstStruct {nullptr};
|
||||
};
|
||||
|
||||
/** Percent property
|
||||
@@ -357,19 +381,21 @@ public:
|
||||
~PropertyIntegerList() override;
|
||||
|
||||
const char* getEditorName() const override
|
||||
{ return "Gui::PropertyEditor::PropertyIntegerListItem"; }
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyIntegerListItem";
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
unsigned int getMemSize () const override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
protected:
|
||||
long getPyValue(PyObject *item) const override;
|
||||
long getPyValue(PyObject* item) const override;
|
||||
};
|
||||
|
||||
/** Integer list properties
|
||||
@@ -396,30 +422,41 @@ public:
|
||||
/** Sets the property
|
||||
*/
|
||||
void setValue(long);
|
||||
void setValue(){;}
|
||||
void setValue()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void addValue (long value){_lValueSet.insert(value);}
|
||||
void setValues (const std::set<long>& values);
|
||||
void addValue(long value)
|
||||
{
|
||||
_lValueSet.insert(value);
|
||||
}
|
||||
void setValues(const std::set<long>& values);
|
||||
|
||||
const std::set<long> &getValues() const{return _lValueSet;}
|
||||
const std::set<long>& getValues() const
|
||||
{
|
||||
return _lValueSet;
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
unsigned int getMemSize () const override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValues() == static_cast<decltype(this)>(&other)->getValues();
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<long> _lValueSet;
|
||||
};
|
||||
@@ -433,7 +470,6 @@ class AppExport PropertyMap: public Property
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* A constructor.
|
||||
* A more elaborate description of the constructor.
|
||||
@@ -450,31 +486,40 @@ public:
|
||||
|
||||
/** Sets the property
|
||||
*/
|
||||
void setValue(){}
|
||||
void setValue(const std::string& key,const std::string& value);
|
||||
void setValues(const std::map<std::string,std::string>&);
|
||||
void setValue()
|
||||
{}
|
||||
void setValue(const std::string& key, const std::string& value);
|
||||
void setValues(const std::map<std::string, std::string>&);
|
||||
|
||||
/// index operator
|
||||
const std::string& operator[] (const std::string& key) const ;
|
||||
const std::string& operator[](const std::string& key) const;
|
||||
|
||||
void set1Value (const std::string& key, const std::string& value){_lValueList.operator[] (key) = value;}
|
||||
void set1Value(const std::string& key, const std::string& value)
|
||||
{
|
||||
_lValueList.operator[](key) = value;
|
||||
}
|
||||
|
||||
const std::map<std::string,std::string> &getValues() const{return _lValueList;}
|
||||
const std::map<std::string, std::string>& getValues() const
|
||||
{
|
||||
return _lValueList;
|
||||
}
|
||||
|
||||
//virtual const char* getEditorName(void) const { return "Gui::PropertyEditor::PropertyStringListItem"; }
|
||||
// virtual const char* getEditorName(void) const { return
|
||||
// "Gui::PropertyEditor::PropertyStringListItem"; }
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
@@ -483,11 +528,10 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string,std::string> _lValueList;
|
||||
std::map<std::string, std::string> _lValueList;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Float properties
|
||||
* This is the father of all properties handling floats.
|
||||
* Use this type only in rare cases. Mostly you want to
|
||||
@@ -515,23 +559,30 @@ public:
|
||||
void setValue(double lValue);
|
||||
double getValue() const;
|
||||
|
||||
const char* getEditorName() const override { return "Gui::PropertyEditor::PropertyFloatItem"; }
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyFloatItem";
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override{return sizeof(double);}
|
||||
unsigned int getMemSize() const override
|
||||
{
|
||||
return sizeof(double);
|
||||
}
|
||||
|
||||
void setPathValue(const App::ObjectIdentifier &path, const boost::any &value) override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier &path) const override;
|
||||
void setPathValue(const App::ObjectIdentifier& path, const boost::any& value) override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier& path) const override;
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
@@ -554,7 +605,6 @@ class AppExport PropertyFloatConstraint: public PropertyFloat
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
|
||||
/** Value Constructor
|
||||
* Construct with explicit Values
|
||||
*/
|
||||
@@ -570,22 +620,21 @@ public:
|
||||
/// Constraint methods
|
||||
//@{
|
||||
/// the boundary struct
|
||||
struct Constraints {
|
||||
struct Constraints
|
||||
{
|
||||
double LowerBound, UpperBound, StepSize;
|
||||
Constraints()
|
||||
: LowerBound(0)
|
||||
, UpperBound(0)
|
||||
, StepSize(0)
|
||||
, candelete(false)
|
||||
{
|
||||
}
|
||||
{}
|
||||
Constraints(double l, double u, double s)
|
||||
: LowerBound(l)
|
||||
, UpperBound(u)
|
||||
, StepSize(s)
|
||||
, candelete(false)
|
||||
{
|
||||
}
|
||||
{}
|
||||
~Constraints() = default;
|
||||
void setDeletable(bool on)
|
||||
{
|
||||
@@ -595,6 +644,7 @@ public:
|
||||
{
|
||||
return candelete;
|
||||
}
|
||||
|
||||
private:
|
||||
bool candelete;
|
||||
};
|
||||
@@ -608,7 +658,7 @@ public:
|
||||
*/
|
||||
void setConstraints(const Constraints* sConstrain);
|
||||
/// get the constraint struct
|
||||
const Constraints* getConstraints() const;
|
||||
const Constraints* getConstraints() const;
|
||||
//@}
|
||||
|
||||
double getMinimum() const;
|
||||
@@ -616,12 +666,14 @@ public:
|
||||
double getStepSize() const;
|
||||
|
||||
const char* getEditorName() const override
|
||||
{ return "Gui::PropertyEditor::PropertyFloatConstraintItem"; }
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyFloatConstraintItem";
|
||||
}
|
||||
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
protected:
|
||||
const Constraints* _ConstStruct{nullptr};
|
||||
const Constraints* _ConstStruct {nullptr};
|
||||
};
|
||||
|
||||
|
||||
@@ -633,11 +685,14 @@ protected:
|
||||
class AppExport PropertyPrecision: public PropertyFloatConstraint
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
PropertyPrecision();
|
||||
~PropertyPrecision() override;
|
||||
const char* getEditorName() const override
|
||||
{ return "Gui::PropertyEditor::PropertyPrecisionItem"; }
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyPrecisionItem";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -646,7 +701,6 @@ class AppExport PropertyFloatList: public PropertyListsT<double>
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* A constructor.
|
||||
* A more elaborate description of the constructor.
|
||||
@@ -660,22 +714,24 @@ public:
|
||||
~PropertyFloatList() override;
|
||||
|
||||
const char* getEditorName() const override
|
||||
{ return "Gui::PropertyEditor::PropertyFloatListItem"; }
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyFloatListItem";
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
void SaveDocFile (Base::Writer &writer) const override;
|
||||
void RestoreDocFile(Base::Reader &reader) override;
|
||||
void SaveDocFile(Base::Writer& writer) const override;
|
||||
void RestoreDocFile(Base::Reader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
unsigned int getMemSize () const override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
protected:
|
||||
double getPyValue(PyObject *item) const override;
|
||||
double getPyValue(PyObject* item) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -687,7 +743,6 @@ class AppExport PropertyString: public Property
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* A constructor.
|
||||
* A more elaborate description of the constructor.
|
||||
@@ -701,27 +756,36 @@ public:
|
||||
~PropertyString() override;
|
||||
|
||||
virtual void setValue(const char* sString);
|
||||
void setValue(const std::string &sString);
|
||||
void setValue(const std::string& sString);
|
||||
const char* getValue() const;
|
||||
const std::string& getStrValue() const
|
||||
{ return _cValue; }
|
||||
bool isEmpty(){return _cValue.empty();}
|
||||
{
|
||||
return _cValue;
|
||||
}
|
||||
bool isEmpty()
|
||||
{
|
||||
return _cValue.empty();
|
||||
}
|
||||
|
||||
const char* getEditorName() const override { return "Gui::PropertyEditor::PropertyStringItem"; }
|
||||
PyObject *getPyObject() override;
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyStringItem";
|
||||
}
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
unsigned int getMemSize () const override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
void setPathValue(const App::ObjectIdentifier &path, const boost::any &value) override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier &path) const override;
|
||||
void setPathValue(const App::ObjectIdentifier& path, const boost::any& value) override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier& path) const override;
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
@@ -741,7 +805,6 @@ class AppExport PropertyUUID: public Property
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* A constructor.
|
||||
* A more elaborate description of the constructor.
|
||||
@@ -755,24 +818,26 @@ public:
|
||||
~PropertyUUID() override;
|
||||
|
||||
|
||||
void setValue(const Base::Uuid &);
|
||||
void setValue(const Base::Uuid&);
|
||||
void setValue(const char* sString);
|
||||
void setValue(const std::string &sString);
|
||||
void setValue(const std::string& sString);
|
||||
const std::string& getValueStr() const;
|
||||
const Base::Uuid& getValue() const;
|
||||
|
||||
//virtual const char* getEditorName(void) const { return "Gui::PropertyEditor::PropertyStringItem"; }
|
||||
PyObject *getPyObject() override;
|
||||
// virtual const char* getEditorName(void) const { return
|
||||
// "Gui::PropertyEditor::PropertyStringItem"; }
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
unsigned int getMemSize () const override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
@@ -787,7 +852,7 @@ private:
|
||||
|
||||
/** Property handling with font names.
|
||||
*/
|
||||
class AppExport PropertyFont : public PropertyString
|
||||
class AppExport PropertyFont: public PropertyString
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -795,9 +860,12 @@ public:
|
||||
PropertyFont();
|
||||
~PropertyFont() override;
|
||||
const char* getEditorName() const override
|
||||
{ return "Gui::PropertyEditor::PropertyFontItem"; }
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyFontItem";
|
||||
}
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
@@ -812,7 +880,6 @@ class AppExport PropertyStringList: public PropertyListsT<std::string>
|
||||
using inherited = PropertyListsT<std::string>;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* A constructor.
|
||||
* A more elaborate description of the constructor.
|
||||
@@ -829,31 +896,32 @@ public:
|
||||
using inherited::setValues;
|
||||
|
||||
const char* getEditorName() const override
|
||||
{ return "Gui::PropertyEditor::PropertyStringListItem"; }
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyStringListItem";
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
protected:
|
||||
std::string getPyValue(PyObject *item) const override;
|
||||
std::string getPyValue(PyObject* item) const override;
|
||||
};
|
||||
|
||||
/** Bool properties
|
||||
* This is the father of all properties handling booleans.
|
||||
*/
|
||||
class AppExport PropertyBool : public Property
|
||||
class AppExport PropertyBool: public Property
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* A constructor.
|
||||
* A more elaborate description of the constructor.
|
||||
@@ -869,23 +937,30 @@ public:
|
||||
void setValue(bool lValue);
|
||||
bool getValue() const;
|
||||
|
||||
const char* getEditorName() const override { return "Gui::PropertyEditor::PropertyBoolItem"; }
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyBoolItem";
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override{return sizeof(bool);}
|
||||
unsigned int getMemSize() const override
|
||||
{
|
||||
return sizeof(bool);
|
||||
}
|
||||
|
||||
void setPathValue(const App::ObjectIdentifier &path, const boost::any &value) override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier &path) const override;
|
||||
void setPathValue(const App::ObjectIdentifier& path, const boost::any& value) override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier& path) const override;
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
@@ -900,24 +975,24 @@ private:
|
||||
/** Bool list properties
|
||||
*
|
||||
*/
|
||||
class AppExport PropertyBoolList : public PropertyListsT<bool,boost::dynamic_bitset<> >
|
||||
class AppExport PropertyBoolList: public PropertyListsT<bool, boost::dynamic_bitset<>>
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
using inherited = PropertyListsT<bool, boost::dynamic_bitset<> >;
|
||||
using inherited = PropertyListsT<bool, boost::dynamic_bitset<>>;
|
||||
|
||||
public:
|
||||
PropertyBoolList();
|
||||
~PropertyBoolList() override;
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
unsigned int getMemSize () const override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
protected:
|
||||
bool getPyValue(PyObject* py) const override;
|
||||
@@ -927,7 +1002,7 @@ protected:
|
||||
/** Color properties
|
||||
* This is the father of all properties handling colors.
|
||||
*/
|
||||
class AppExport PropertyColor : public Property
|
||||
class AppExport PropertyColor: public Property
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -946,28 +1021,35 @@ public:
|
||||
|
||||
/** Sets the property
|
||||
*/
|
||||
void setValue(const Color &col);
|
||||
void setValue(float r, float g, float b, float a=0.0F);
|
||||
void setValue(const Color& col);
|
||||
void setValue(float r, float g, float b, float a = 0.0F);
|
||||
void setValue(uint32_t rgba);
|
||||
|
||||
/** This method returns a string representation of the property
|
||||
*/
|
||||
const Color &getValue() const;
|
||||
const Color& getValue() const;
|
||||
|
||||
const char* getEditorName() const override { return "Gui::PropertyEditor::PropertyColorItem"; }
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyColorItem";
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject* py) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize () const override{return sizeof(Color);}
|
||||
unsigned int getMemSize() const override
|
||||
{
|
||||
return sizeof(Color);
|
||||
}
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
@@ -984,7 +1066,6 @@ class AppExport PropertyColorList: public PropertyListsT<Color>
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* A constructor.
|
||||
* A more elaborate description of the constructor.
|
||||
@@ -997,17 +1078,17 @@ public:
|
||||
*/
|
||||
~PropertyColorList() override;
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
void SaveDocFile (Base::Writer &writer) const override;
|
||||
void RestoreDocFile(Base::Reader &reader) override;
|
||||
void SaveDocFile(Base::Writer& writer) const override;
|
||||
void RestoreDocFile(Base::Reader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
unsigned int getMemSize () const override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
protected:
|
||||
Color getPyValue(PyObject* py) const override;
|
||||
@@ -1118,7 +1199,8 @@ public:
|
||||
{
|
||||
PropertyListsT<Material>::setValue(materials);
|
||||
}
|
||||
void setValues(const std::vector<App::Material>& newValues = std::vector<App::Material>()) override;
|
||||
void
|
||||
setValues(const std::vector<App::Material>& newValues = std::vector<App::Material>()) override;
|
||||
void setValue(const Material& mat);
|
||||
void setValue(int index, const Material& mat);
|
||||
|
||||
@@ -1196,7 +1278,8 @@ protected:
|
||||
Material getPyValue(PyObject* py) const override;
|
||||
|
||||
private:
|
||||
enum Format {
|
||||
enum Format
|
||||
{
|
||||
Version_0,
|
||||
Version_1,
|
||||
Version_2,
|
||||
@@ -1206,7 +1289,7 @@ private:
|
||||
void RestoreDocFileV0(uint32_t count, Base::Reader& reader);
|
||||
void RestoreDocFileV3(Base::Reader& reader);
|
||||
|
||||
void writeString(Base::OutputStream& str, const std::string &value) const;
|
||||
void writeString(Base::OutputStream& str, const std::string& value) const;
|
||||
void readString(Base::InputStream& str, std::string& value);
|
||||
|
||||
void verifyIndex(int index) const;
|
||||
@@ -1222,21 +1305,24 @@ private:
|
||||
* In Python, this property can be assigned a type string to create a dynamic FreeCAD
|
||||
* object, and then read back as the Python binding of the newly created object.
|
||||
*/
|
||||
class AppExport PropertyPersistentObject: public PropertyString {
|
||||
class AppExport PropertyPersistentObject: public PropertyString
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
using inherited = PropertyString;
|
||||
|
||||
public:
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
void setValue(const char* type) override;
|
||||
|
||||
void Save (Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const Property &from) override;
|
||||
unsigned int getMemSize () const override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
std::shared_ptr<Base::Persistence> getObject() const {
|
||||
std::shared_ptr<Base::Persistence> getObject() const
|
||||
{
|
||||
return _pObject;
|
||||
}
|
||||
|
||||
@@ -1244,6 +1330,6 @@ protected:
|
||||
std::shared_ptr<Base::Persistence> _pObject;
|
||||
};
|
||||
|
||||
} // namespace App
|
||||
} // namespace App
|
||||
|
||||
#endif // APP_PROPERTYSTANDARD_H
|
||||
#endif // APP_PROPERTYSTANDARD_H
|
||||
|
||||
+44
-34
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <cfloat>
|
||||
#include <cfloat>
|
||||
#endif
|
||||
|
||||
#include <Base/QuantityPy.h>
|
||||
@@ -37,8 +37,8 @@ using namespace Base;
|
||||
using namespace std;
|
||||
|
||||
|
||||
const PropertyQuantityConstraint::Constraints LengthStandard = {0.0,DBL_MAX,1.0};
|
||||
const PropertyQuantityConstraint::Constraints AngleStandard = {-360,360,1.0};
|
||||
const PropertyQuantityConstraint::Constraints LengthStandard = {0.0, DBL_MAX, 1.0};
|
||||
const PropertyQuantityConstraint::Constraints AngleStandard = {-360, 360, 1.0};
|
||||
|
||||
//**************************************************************************
|
||||
// PropertyQuantity
|
||||
@@ -48,7 +48,7 @@ TYPESYSTEM_SOURCE(App::PropertyQuantity, App::PropertyFloat)
|
||||
|
||||
Base::Quantity PropertyQuantity::getQuantityValue() const
|
||||
{
|
||||
return Quantity(_dValue,_Unit);
|
||||
return Quantity(_dValue, _Unit);
|
||||
}
|
||||
|
||||
const char* PropertyQuantity::getEditorName() const
|
||||
@@ -56,24 +56,26 @@ const char* PropertyQuantity::getEditorName() const
|
||||
return "Gui::PropertyEditor::PropertyUnitItem";
|
||||
}
|
||||
|
||||
PyObject *PropertyQuantity::getPyObject()
|
||||
PyObject* PropertyQuantity::getPyObject()
|
||||
{
|
||||
return new QuantityPy (new Quantity(_dValue,_Unit));
|
||||
return new QuantityPy(new Quantity(_dValue, _Unit));
|
||||
}
|
||||
|
||||
Base::Quantity PropertyQuantity::createQuantityFromPy(PyObject *value)
|
||||
Base::Quantity PropertyQuantity::createQuantityFromPy(PyObject* value)
|
||||
{
|
||||
Base::Quantity quant;
|
||||
|
||||
if (PyUnicode_Check(value)){
|
||||
if (PyUnicode_Check(value)) {
|
||||
quant = Quantity::parse(QString::fromUtf8(PyUnicode_AsUTF8(value)));
|
||||
}
|
||||
else if (PyFloat_Check(value))
|
||||
quant = Quantity(PyFloat_AsDouble(value),_Unit);
|
||||
else if (PyLong_Check(value))
|
||||
quant = Quantity(double(PyLong_AsLong(value)),_Unit);
|
||||
else if (PyFloat_Check(value)) {
|
||||
quant = Quantity(PyFloat_AsDouble(value), _Unit);
|
||||
}
|
||||
else if (PyLong_Check(value)) {
|
||||
quant = Quantity(double(PyLong_AsLong(value)), _Unit);
|
||||
}
|
||||
else if (PyObject_TypeCheck(value, &(QuantityPy::Type))) {
|
||||
Base::QuantityPy *pcObject = static_cast<Base::QuantityPy*>(value);
|
||||
Base::QuantityPy* pcObject = static_cast<Base::QuantityPy*>(value);
|
||||
quant = *(pcObject->getQuantityPtr());
|
||||
}
|
||||
else {
|
||||
@@ -85,45 +87,47 @@ Base::Quantity PropertyQuantity::createQuantityFromPy(PyObject *value)
|
||||
return quant;
|
||||
}
|
||||
|
||||
void PropertyQuantity::setPyObject(PyObject *value)
|
||||
void PropertyQuantity::setPyObject(PyObject* value)
|
||||
{
|
||||
// Set the unit if Unit object supplied, else check the unit
|
||||
// and set the value
|
||||
|
||||
if (PyObject_TypeCheck(value, &(UnitPy::Type))) {
|
||||
Base::UnitPy *pcObject = static_cast<Base::UnitPy*>(value);
|
||||
Base::UnitPy* pcObject = static_cast<Base::UnitPy*>(value);
|
||||
Base::Unit unit = *(pcObject->getUnitPtr());
|
||||
aboutToSetValue();
|
||||
_Unit = unit;
|
||||
hasSetValue();
|
||||
}
|
||||
else {
|
||||
Base::Quantity quant= createQuantityFromPy(value);
|
||||
Base::Quantity quant = createQuantityFromPy(value);
|
||||
|
||||
Unit unit = quant.getUnit();
|
||||
if (unit.isEmpty()){
|
||||
if (unit.isEmpty()) {
|
||||
PropertyFloat::setValue(quant.getValue());
|
||||
return;
|
||||
}
|
||||
|
||||
if (unit != _Unit)
|
||||
if (unit != _Unit) {
|
||||
throw Base::UnitsMismatchError("Not matching Unit!");
|
||||
}
|
||||
|
||||
PropertyFloat::setValue(quant.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyQuantity::setPathValue(const ObjectIdentifier & /*path*/, const boost::any &value)
|
||||
void PropertyQuantity::setPathValue(const ObjectIdentifier& /*path*/, const boost::any& value)
|
||||
{
|
||||
auto q = App::anyToQuantity(value);
|
||||
aboutToSetValue();
|
||||
if(!q.getUnit().isEmpty())
|
||||
if (!q.getUnit().isEmpty()) {
|
||||
_Unit = q.getUnit();
|
||||
_dValue=q.getValue();
|
||||
}
|
||||
_dValue = q.getValue();
|
||||
setValue(q.getValue());
|
||||
}
|
||||
|
||||
const boost::any PropertyQuantity::getPathValue(const ObjectIdentifier & /*path*/) const
|
||||
const boost::any PropertyQuantity::getPathValue(const ObjectIdentifier& /*path*/) const
|
||||
{
|
||||
return Quantity(_dValue, _Unit);
|
||||
}
|
||||
@@ -145,55 +149,61 @@ const char* PropertyQuantityConstraint::getEditorName() const
|
||||
return "Gui::PropertyEditor::PropertyUnitConstraintItem";
|
||||
}
|
||||
|
||||
const PropertyQuantityConstraint::Constraints* PropertyQuantityConstraint::getConstraints() const
|
||||
const PropertyQuantityConstraint::Constraints* PropertyQuantityConstraint::getConstraints() const
|
||||
{
|
||||
return _ConstStruct;
|
||||
}
|
||||
|
||||
double PropertyQuantityConstraint::getMinimum() const
|
||||
{
|
||||
if (_ConstStruct)
|
||||
if (_ConstStruct) {
|
||||
return _ConstStruct->LowerBound;
|
||||
}
|
||||
return std::numeric_limits<double>::min();
|
||||
}
|
||||
|
||||
double PropertyQuantityConstraint::getMaximum() const
|
||||
{
|
||||
if (_ConstStruct)
|
||||
if (_ConstStruct) {
|
||||
return _ConstStruct->UpperBound;
|
||||
}
|
||||
return std::numeric_limits<double>::max();
|
||||
}
|
||||
|
||||
double PropertyQuantityConstraint::getStepSize() const
|
||||
{
|
||||
if (_ConstStruct)
|
||||
if (_ConstStruct) {
|
||||
return _ConstStruct->StepSize;
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
void PropertyQuantityConstraint::setPyObject(PyObject *value)
|
||||
void PropertyQuantityConstraint::setPyObject(PyObject* value)
|
||||
{
|
||||
Base::Quantity quant= createQuantityFromPy(value);
|
||||
Base::Quantity quant = createQuantityFromPy(value);
|
||||
|
||||
Unit unit = quant.getUnit();
|
||||
double temp = quant.getValue();
|
||||
if (_ConstStruct) {
|
||||
if (temp > _ConstStruct->UpperBound)
|
||||
if (temp > _ConstStruct->UpperBound) {
|
||||
temp = _ConstStruct->UpperBound;
|
||||
else if (temp < _ConstStruct->LowerBound)
|
||||
}
|
||||
else if (temp < _ConstStruct->LowerBound) {
|
||||
temp = _ConstStruct->LowerBound;
|
||||
}
|
||||
}
|
||||
quant.setValue(temp);
|
||||
|
||||
if (unit.isEmpty()){
|
||||
PropertyFloat::setValue(quant.getValue()); // clazy:exclude=skipped-base-method
|
||||
if (unit.isEmpty()) {
|
||||
PropertyFloat::setValue(quant.getValue()); // clazy:exclude=skipped-base-method
|
||||
return;
|
||||
}
|
||||
|
||||
if (unit != _Unit)
|
||||
if (unit != _Unit) {
|
||||
throw Base::UnitsMismatchError("Not matching Unit!");
|
||||
}
|
||||
|
||||
PropertyFloat::setValue(quant.getValue()); // clazy:exclude=skipped-base-method
|
||||
PropertyFloat::setValue(quant.getValue()); // clazy:exclude=skipped-base-method
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
|
||||
+43
-24
@@ -29,7 +29,8 @@
|
||||
#include "PropertyStandard.h"
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
class Writer;
|
||||
}
|
||||
|
||||
@@ -39,7 +40,7 @@ namespace App
|
||||
/** Float with Unit property
|
||||
* This is a property for float with a predefined Unit associated.
|
||||
*/
|
||||
class AppExport PropertyQuantity : public PropertyFloat
|
||||
class AppExport PropertyQuantity: public PropertyFloat
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -51,35 +52,49 @@ public:
|
||||
|
||||
const char* getEditorName() const override;
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
void setPyObject(PyObject *) override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject*) override;
|
||||
|
||||
void setUnit(const Base::Unit &u) {_Unit = u;}
|
||||
const Base::Unit &getUnit() const {return _Unit;}
|
||||
void setUnit(const Base::Unit& u)
|
||||
{
|
||||
_Unit = u;
|
||||
}
|
||||
const Base::Unit& getUnit() const
|
||||
{
|
||||
return _Unit;
|
||||
}
|
||||
|
||||
void setValue(double lValue) { PropertyFloat::setValue(lValue); }
|
||||
double getValue() const { return PropertyFloat::getValue(); }
|
||||
void setValue(double lValue)
|
||||
{
|
||||
PropertyFloat::setValue(lValue);
|
||||
}
|
||||
double getValue() const
|
||||
{
|
||||
return PropertyFloat::getValue();
|
||||
}
|
||||
|
||||
void setPathValue(const App::ObjectIdentifier &path, const boost::any &value) override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier &path) const override;
|
||||
void setPathValue(const App::ObjectIdentifier& path, const boost::any& value) override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier& path) const override;
|
||||
|
||||
bool isSame(const Property &other) const override {
|
||||
if (&other == this)
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue()
|
||||
&& _Unit == static_cast<decltype(this)>(&other)->_Unit;
|
||||
}
|
||||
|
||||
protected:
|
||||
Base::Quantity createQuantityFromPy(PyObject *value);
|
||||
Base::Quantity createQuantityFromPy(PyObject* value);
|
||||
Base::Unit _Unit;
|
||||
};
|
||||
|
||||
/** Float with Unit property
|
||||
* This is a property for float with a predefined Unit associated.
|
||||
*/
|
||||
class AppExport PropertyQuantityConstraint : public PropertyQuantity
|
||||
class AppExport PropertyQuantityConstraint: public PropertyQuantity
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -90,7 +105,8 @@ public:
|
||||
/// Constraint methods
|
||||
//@{
|
||||
/// the boundary struct
|
||||
struct Constraints {
|
||||
struct Constraints
|
||||
{
|
||||
double LowerBound, UpperBound, StepSize;
|
||||
};
|
||||
/** setting the boundaries
|
||||
@@ -103,7 +119,7 @@ public:
|
||||
*/
|
||||
void setConstraints(const Constraints* sConstrain);
|
||||
/// get the constraint struct
|
||||
const Constraints* getConstraints() const;
|
||||
const Constraints* getConstraints() const;
|
||||
//@}
|
||||
|
||||
double getMinimum() const;
|
||||
@@ -111,10 +127,10 @@ public:
|
||||
double getStepSize() const;
|
||||
|
||||
const char* getEditorName() const override;
|
||||
void setPyObject(PyObject *) override;
|
||||
void setPyObject(PyObject*) override;
|
||||
|
||||
private:
|
||||
const Constraints* _ConstStruct{nullptr};
|
||||
const Constraints* _ConstStruct {nullptr};
|
||||
};
|
||||
|
||||
// ------------------------------------------------------
|
||||
@@ -158,7 +174,10 @@ class AppExport PropertyAngle: public PropertyQuantityConstraint
|
||||
public:
|
||||
PropertyAngle();
|
||||
~PropertyAngle() override = default;
|
||||
const char *getEditorName() const override { return "Gui::PropertyEditor::PropertyAngleItem"; }
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "Gui::PropertyEditor::PropertyAngleItem";
|
||||
}
|
||||
};
|
||||
|
||||
/** Area property
|
||||
@@ -425,7 +444,7 @@ public:
|
||||
|
||||
/** InverseVolume property
|
||||
* This is a property for representing the reciprocal of volume. It is basically a float
|
||||
* property. which must not be negative. On the Gui it has a quantity like 1/m^3.
|
||||
* property. which must not be negative. On the Gui it has a quantity like 1/m^3.
|
||||
*/
|
||||
class AppExport PropertyInverseVolume: public PropertyQuantity
|
||||
{
|
||||
@@ -514,11 +533,11 @@ public:
|
||||
~PropertyMagneticFluxDensity() override = default;
|
||||
};
|
||||
|
||||
/** Magnetization property
|
||||
/** Magnetization property
|
||||
* This is a property for representing magnetizations. It is basically a float
|
||||
* property. On the Gui it has a quantity like A/m.
|
||||
*/
|
||||
class AppExport PropertyMagnetization: public PropertyQuantity
|
||||
class AppExport PropertyMagnetization: public PropertyQuantity
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -852,6 +871,6 @@ public:
|
||||
~PropertyYoungsModulus() override = default;
|
||||
};
|
||||
|
||||
}// namespace App
|
||||
} // namespace App
|
||||
|
||||
#endif// APP_PROPERTYUNITS_H
|
||||
#endif // APP_PROPERTYUNITS_H
|
||||
|
||||
@@ -154,8 +154,8 @@ struct DocumentP
|
||||
Path tmp);
|
||||
std::vector<App::DocumentObject*>
|
||||
topologicalSort(const std::vector<App::DocumentObject*>& objects) const;
|
||||
static std::vector<App::DocumentObject*> partialTopologicalSort(
|
||||
const std::vector<App::DocumentObject*>& objects);
|
||||
static std::vector<App::DocumentObject*>
|
||||
partialTopologicalSort(const std::vector<App::DocumentObject*>& objects);
|
||||
static void checkStringHasher(const Base::XMLReader& reader);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user