diff --git a/src/App/Property.cpp b/src/App/Property.cpp index 1c7bdce0d4..6bed9ef734 100644 --- a/src/App/Property.cpp +++ b/src/App/Property.cpp @@ -276,6 +276,17 @@ void Property::setStatus(Status pos, bool on) { bits.set(pos,on); setStatusValue(bits.to_ulong()); } + +bool Property::isSame(const Property &other) const { + if(other.getTypeId() != getTypeId() || getMemSize() != other.getMemSize()) + return false; + + Base::StringWriter writer,writer2; + Save(writer); + other.Save(writer2); + return writer.getString() == writer2.getString(); +} + //************************************************************************** //************************************************************************** // PropertyListsBase diff --git a/src/App/Property.h b/src/App/Property.h index 5c46f51662..f2ef4efeda 100644 --- a/src/App/Property.h +++ b/src/App/Property.h @@ -236,6 +236,9 @@ public: /// Called before a child property changing value virtual void aboutToSetChildValue(Property &) {} + /// Compare if this property has the same content as the given one + virtual bool isSame(const Property &other) const; + friend class PropertyContainer; friend struct PropertyData; friend class DynamicProperty; @@ -492,6 +495,11 @@ public: const_reference operator[] (int idx) const {return _lValueList[idx];} + virtual bool isSame(const Property &other) const override { + return this->getTypeId() == other.getTypeId() + && this->getValue() == static_cast(&other)->getValue(); + } + virtual void setPyObject(PyObject *value) override { try { setValue(getPyValue(value)); diff --git a/src/App/PropertyFile.h b/src/App/PropertyFile.h index 349bc2e7c5..9bc36df394 100644 --- a/src/App/PropertyFile.h +++ b/src/App/PropertyFile.h @@ -103,6 +103,13 @@ public: virtual void Paste(const Property &from); virtual unsigned int getMemSize (void) const; + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && _BaseFileName == static_cast(&other)->_BaseFileName + && _OriginalName == static_cast(&other)->_OriginalName + && _cValue == static_cast(&other)->_cValue; + } + /** 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 diff --git a/src/App/PropertyGeo.h b/src/App/PropertyGeo.h index f22be71507..4291fdb99b 100644 --- a/src/App/PropertyGeo.h +++ b/src/App/PropertyGeo.h @@ -108,6 +108,11 @@ public: return Base::Unit(); } + virtual bool isSame(const Property &other) const override { + return getTypeId() == other.getTypeId() + && getValue() == static_cast(&other)->getValue(); + } + private: Base::Vector3d _cVec; }; @@ -278,6 +283,11 @@ public: return sizeof(Base::Matrix4D); } + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getValue() == static_cast(&other)->getValue(); + } + private: Base::Matrix4D _cMat; }; @@ -345,6 +355,11 @@ public: return sizeof(Base::Placement); } + virtual bool isSame(const Property &other) const override { + return getTypeId() == other.getTypeId() + && getValue() == static_cast(&other)->getValue(); + } + static const Placement Null; private: diff --git a/src/App/PropertyLinks.cpp b/src/App/PropertyLinks.cpp index 5bdbb5286f..2b82781b6c 100644 --- a/src/App/PropertyLinks.cpp +++ b/src/App/PropertyLinks.cpp @@ -84,6 +84,27 @@ void PropertyLinkBase::hasSetValue() { Property::hasSetValue(); } +bool PropertyLinkBase::isSame(const Property &other) const +{ + if(other.isDerivedFrom(PropertyLinkBase::getClassTypeId()) + || getScope() != static_cast(&other)->getScope()) + return false; + + static std::vector ret; + static std::vector subs; + static std::vector ret2; + static std::vector subs2; + + ret.clear(); + subs.clear(); + ret2.clear(); + subs2.clear(); + getLinks(ret,true,&subs,false); + static_cast(&other)->getLinks(ret2,true,&subs2,true); + + return ret==ret2 && subs==subs2; +} + void PropertyLinkBase::unregisterElementReference() { } diff --git a/src/App/PropertyLinks.h b/src/App/PropertyLinks.h index 66c4d9bb80..5f527ba765 100644 --- a/src/App/PropertyLinks.h +++ b/src/App/PropertyLinks.h @@ -93,8 +93,8 @@ public: * Retrieve what kind of links are allowed. Only in the Local GeoFeatureGroup, in this and * all Childs or to all objects within the Glocal scope. */ - LinkScope getScope() {return _pcScope;}; - + LinkScope getScope() const {return _pcScope;}; + protected: LinkScope _pcScope = LinkScope::Local; }; @@ -288,6 +288,8 @@ public: } //@} + virtual bool isSame(const Property &other) const override; + /** Enable/disable temporary holding external object without throwing exception * * Warning, non-PropertyXLink related property does not have internal diff --git a/src/App/PropertyStandard.cpp b/src/App/PropertyStandard.cpp index 9898d94277..3344c9a29a 100644 --- a/src/App/PropertyStandard.cpp +++ b/src/App/PropertyStandard.cpp @@ -207,7 +207,7 @@ void PropertyPath::setValue(const char * Path) hasSetValue(); } -boost::filesystem::path PropertyPath::getValue() const +const boost::filesystem::path &PropertyPath::getValue(void) const { return _cValue; } diff --git a/src/App/PropertyStandard.h b/src/App/PropertyStandard.h index 49bc7509d3..2e5766e464 100644 --- a/src/App/PropertyStandard.h +++ b/src/App/PropertyStandard.h @@ -81,6 +81,11 @@ public: virtual void setPathValue(const App::ObjectIdentifier & path, const boost::any & value); virtual const boost::any getPathValue(const App::ObjectIdentifier & /*path*/) const { return _lValue; } + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getValue() == static_cast(&other)->getValue(); + } + protected: long _lValue; }; @@ -107,7 +112,7 @@ public: /** This method returns a string representation of the property */ - boost::filesystem::path getValue(void) const; + const boost::filesystem::path &getValue(void) const; virtual const char* getEditorName(void) const { return "Gui::PropertyEditor::PropertyPathItem"; } @@ -122,6 +127,11 @@ public: virtual unsigned int getMemSize (void) const; + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getValue() == static_cast(&other)->getValue(); + } + protected: boost::filesystem::path _cValue; }; @@ -217,6 +227,11 @@ public: virtual const boost::any getPathValue(const App::ObjectIdentifier & /*path*/) const; virtual bool getPyPathValue(const ObjectIdentifier &path, Py::Object &r) const; + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getEnum() == static_cast(&other)->getEnum(); + } + private: Enumeration _enum; std::string _editorTypeName; @@ -391,6 +406,10 @@ public: virtual void Paste(const Property &from); virtual unsigned int getMemSize (void) const; + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getValues() == static_cast(&other)->getValues(); + } private: std::set _lValueSet; }; @@ -444,7 +463,11 @@ public: virtual void Paste(const Property &from); virtual unsigned int getMemSize (void) const; - + + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getValues() == static_cast(&other)->getValues(); + } private: std::map _lValueList; @@ -495,6 +518,11 @@ public: void setPathValue(const App::ObjectIdentifier &path, const boost::any &value); const boost::any getPathValue(const App::ObjectIdentifier &path) const; + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getValue() == static_cast(&other)->getValue(); + } + protected: double _dValue; }; @@ -679,6 +707,11 @@ public: void setPathValue(const App::ObjectIdentifier &path, const boost::any &value); const boost::any getPathValue(const App::ObjectIdentifier &path) const; + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getStrValue() == static_cast(&other)->getStrValue(); + } + protected: std::string _cValue; }; @@ -722,6 +755,11 @@ public: virtual void Paste(const Property &from); virtual unsigned int getMemSize (void) const; + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && _uuid.getValue() == static_cast(&other)->_uuid.getValue(); + } + private: Base::Uuid _uuid; }; @@ -738,6 +776,11 @@ public: virtual ~PropertyFont(); virtual const char* getEditorName(void) const { return "Gui::PropertyEditor::PropertyFontItem"; } + + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getValue() == static_cast(&other)->getValue(); + } }; class AppExport PropertyStringList: public PropertyListsT @@ -819,6 +862,11 @@ public: void setPathValue(const App::ObjectIdentifier &path, const boost::any &value); const boost::any getPathValue(const App::ObjectIdentifier &path) const; + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getValue() == static_cast(&other)->getValue(); + } + private: bool _lValue; }; @@ -892,7 +940,11 @@ public: virtual void Paste(const Property &from); virtual unsigned int getMemSize (void) const{return sizeof(Color);} - + + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getValue() == static_cast(&other)->getValue(); + } private: Color _cCol; @@ -979,6 +1031,11 @@ public: virtual void Paste(const Property &from); virtual unsigned int getMemSize (void) const{return sizeof(_cMat);} + + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getValue() == static_cast(&other)->getValue(); + } private: Material _cMat; diff --git a/src/App/PropertyUnits.h b/src/App/PropertyUnits.h index fdc4b453f3..19b0cbb103 100644 --- a/src/App/PropertyUnits.h +++ b/src/App/PropertyUnits.h @@ -71,6 +71,12 @@ public: virtual void setPathValue(const App::ObjectIdentifier &path, const boost::any &value); virtual const boost::any getPathValue(const App::ObjectIdentifier &path) const; + virtual bool isSame(const Property &other) const { + return getTypeId() == other.getTypeId() + && getValue() == static_cast(&other)->getValue() + && _Unit == static_cast(&other)->_Unit; + } + protected: Base::Quantity createQuantityFromPy(PyObject *value); Base::Unit _Unit;