Merge pull request #25143 from furgo16/issue_24571

App: cherry-pick - Implement Save() & Restore() for int/float constraint properties
This commit is contained in:
Chris Hennes
2026-02-03 21:04:50 +01:00
committed by GitHub
3 changed files with 119 additions and 0 deletions

View File

@@ -770,6 +770,54 @@ void PropertyIntegerConstraint::setPyObject(PyObject* value)
}
}
void PropertyIntegerConstraint::Save(Base::Writer& writer) const
{
writer.Stream() << writer.ind()
<< "<Integer value=\"" << _lValue << "\"";
if (_ConstStruct && _ConstStruct->isDeletable()) {
long minimum = _ConstStruct->LowerBound;
long maximum = _ConstStruct->UpperBound;
long stepsize = _ConstStruct->StepSize;
writer.Stream() << " min=\"" << minimum << "\""
<< " max=\"" << maximum << "\""
<< " step=\"" << stepsize << "\"";
}
writer.Stream() << "/>\n";
}
void PropertyIntegerConstraint::Restore(Base::XMLReader& reader)
{
// read my Element
reader.readElement("Integer");
// get the value of my Attribute
setValue(reader.getAttribute<long>("value"));
bool createConstraint = false;
long minimum = std::numeric_limits<int>::lowest();
long maximum = std::numeric_limits<int>::max();
long stepsize = 1.0;
if (reader.hasAttribute("min")) {
minimum = reader.getAttribute<long>("min");
createConstraint = true;
}
if (reader.hasAttribute("max")) {
maximum = reader.getAttribute<long>("max");
createConstraint = true;
}
if (reader.hasAttribute("step")) {
stepsize = reader.getAttribute<long>("step");
}
if (createConstraint) {
Constraints* c = new Constraints();
c->setDeletable(true);
c->LowerBound = minimum;
c->UpperBound = maximum;
c->StepSize = stepsize;
setConstraints(c);
}
}
//**************************************************************************
//**************************************************************************
// PropertyPercent
@@ -1272,6 +1320,54 @@ void PropertyFloatConstraint::setPyObject(PyObject* value)
}
}
void PropertyFloatConstraint::Save(Base::Writer& writer) const
{
writer.Stream() << writer.ind()
<< "<Float value=\"" << _dValue << "\"";
if (_ConstStruct && _ConstStruct->isDeletable()) {
double minimum = _ConstStruct->LowerBound;
double maximum = _ConstStruct->UpperBound;
double stepsize = _ConstStruct->StepSize;
writer.Stream() << " min=\"" << minimum << "\""
<< " max=\"" << maximum << "\""
<< " step=\"" << stepsize << "\"";
}
writer.Stream() << "/>\n";
}
void PropertyFloatConstraint::Restore(Base::XMLReader& reader)
{
// read my Element
reader.readElement("Float");
// get the value of my Attribute
setValue(reader.getAttribute<double>("value"));
bool createConstraint = false;
double minimum = std::numeric_limits<double>::lowest();
double maximum = std::numeric_limits<double>::max();
double stepsize = 1.0;
if (reader.hasAttribute("min")) {
minimum = reader.getAttribute<double>("min");
createConstraint = true;
}
if (reader.hasAttribute("max")) {
maximum = reader.getAttribute<double>("max");
createConstraint = true;
}
if (reader.hasAttribute("step")) {
stepsize = reader.getAttribute<double>("step");
}
if (createConstraint) {
Constraints* c = new Constraints();
c->setDeletable(true);
c->LowerBound = minimum;
c->UpperBound = maximum;
c->StepSize = stepsize;
setConstraints(c);
}
}
//**************************************************************************
// PropertyPrecision
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

View File

@@ -339,6 +339,9 @@ public:
}
void setPyObject(PyObject* py) override;
void Save(Base::Writer& writer) const override;
void Restore(Base::XMLReader& reader) override;
protected:
const Constraints* _ConstStruct {nullptr};
};
@@ -673,6 +676,9 @@ public:
void setPyObject(PyObject* py) override;
void Save(Base::Writer& writer) const override;
void Restore(Base::XMLReader& reader) override;
protected:
const Constraints* _ConstStruct {nullptr};
};

View File

@@ -75,6 +75,23 @@ class DocumentBasicCases(unittest.TestCase):
FreeCAD.closeDocument(doc.Name)
self.Doc = FreeCAD.newDocument("CreateTest")
def testIssue24571(self):
obj = self.Doc.addObject("App::FeatureTest", "Object")
obj.ConstraintInt = (50, 0, 100, 1)
obj.ConstraintFloat = (50.0, 0.0, 100.0, 1.0)
self.Doc = self.saveAndRestore()
obj = self.Doc.getObject("Object")
# int
obj.ConstraintInt = -1
self.assertEqual(obj.ConstraintInt, 0)
obj.ConstraintInt = 101
self.assertEqual(obj.ConstraintInt, 100)
# float
obj.ConstraintFloat = -1.0
self.assertEqual(obj.ConstraintFloat, 0.0)
obj.ConstraintFloat = 101.0
self.assertEqual(obj.ConstraintFloat, 100.0)
def testAccessByNameOrID(self):
obj = self.Doc.addObject("App::DocumentObject", "MyName")