diff --git a/src/App/ExtensionContainer.cpp b/src/App/ExtensionContainer.cpp
index fdcd5a14b8..88aaca16f3 100644
--- a/src/App/ExtensionContainer.cpp
+++ b/src/App/ExtensionContainer.cpp
@@ -418,9 +418,9 @@ void ExtensionContainer::readExtension(Base::DocumentReader &reader,XERCES_CPP_N
throw Base::TypeError(str.str());
}
ext->initExtension(this);
- if( strcmp(ext->getExtensionTypeId().getName(), type_cstr) == 0 )
- ext->extensionRestore(reader);
}
+ if (ext && strcmp(ext->getExtensionTypeId().getName(), type_cstr) == 0)
+ ext->extensionRestore(reader);
}
catch (const Base::XMLParseException&) {
throw; // re-throw
diff --git a/src/App/PropertyGeo.cpp b/src/App/PropertyGeo.cpp
index 7fb82d88c8..9bccd9847e 100644
--- a/src/App/PropertyGeo.cpp
+++ b/src/App/PropertyGeo.cpp
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include
#include
@@ -40,6 +41,7 @@
#include "Placement.h"
#include "ObjectIdentifier.h"
+#include
using namespace App;
using namespace Base;
@@ -152,6 +154,25 @@ void PropertyVector::Restore(Base::XMLReader &reader)
hasSetValue();
}
+void PropertyVector::Restore(Base::DocumentReader &reader,XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *ContainerDOM)
+{
+ // read my Element
+ auto PropertyVectorDOM = reader.FindElement(ContainerDOM,"PropertyVector");
+ if(PropertyVectorDOM){
+ // get the value of my Attribute
+ const char* valueX_cstr = reader.GetAttribute(PropertyVectorDOM,"valueX");
+ const char* valueY_cstr = reader.GetAttribute(PropertyVectorDOM,"valueY");
+ const char* valueZ_cstr = reader.GetAttribute(PropertyVectorDOM,"valueZ");
+ if(valueX_cstr || valueY_cstr || valueZ_cstr){
+ aboutToSetValue();
+ _cVec.x = reader.ContentToFloat(valueX_cstr);
+ _cVec.y = reader.ContentToFloat(valueY_cstr);
+ _cVec.z = reader.ContentToFloat(valueZ_cstr);
+ hasSetValue();
+ }
+ }
+}
+
Property *PropertyVector::Copy() const
{
diff --git a/src/App/PropertyGeo.h b/src/App/PropertyGeo.h
index 62d1f1299c..9e17db026e 100644
--- a/src/App/PropertyGeo.h
+++ b/src/App/PropertyGeo.h
@@ -89,6 +89,7 @@ public:
void Save (Base::Writer &writer) const override;
void Restore(Base::XMLReader &reader) override;
+ void Restore(Base::DocumentReader &reader, XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *containerEl) override;
Property *Copy() const override;
void Paste(const Property &from) override;
@@ -273,7 +274,7 @@ public:
void setPyObject(PyObject *) override;
void Save (Base::Writer &writer) const override;
- void Restore(Base::XMLReader &reader) override;
+ void Restore(Base::XMLReader &reader) override;
Property *Copy() const override;
void Paste(const Property &from) override;
diff --git a/src/App/PropertyPythonObject.cpp b/src/App/PropertyPythonObject.cpp
index 4fa12a9ba9..00618b8c12 100644
--- a/src/App/PropertyPythonObject.cpp
+++ b/src/App/PropertyPythonObject.cpp
@@ -30,8 +30,13 @@
#include
#include
#include
+#include
#include
+//#ifndef _PreComp_
+//# include
+//#endif
+
#include "PropertyPythonObject.h"
#include "DocumentObject.h"
@@ -264,6 +269,37 @@ void PropertyPythonObject::restoreObject(Base::XMLReader &reader)
}
}
+void PropertyPythonObject::restoreObject(Base::DocumentReader &reader,XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *ContainerDOM)
+{
+ Base::PyGILStateLocker lock;
+ try {
+ PropertyContainer* parent = this->getContainer();
+ const char* object_cstr = reader.GetAttribute(ContainerDOM,"object");
+ if (object_cstr) {
+ if (strcmp(object_cstr,"yes") == 0) {
+ Py::Object obj = Py::asObject(parent->getPyObject());
+ this->object.setAttr("__object__", obj);
+ }
+ }
+ const char* vobject_cstr = reader.GetAttribute(ContainerDOM,"vobject");
+ if (vobject_cstr) {
+ if (strcmp(vobject_cstr,"yes") == 0) {
+ Py::Object obj = Py::asObject(parent->getPyObject());
+ this->object.setAttr("__vobject__", obj);
+ }
+ }
+ }
+ catch (Py::Exception& e) {
+ e.clear();
+ }
+ catch (const Base::Exception& e) {
+ Base::Console().Error("%s\n",e.what());
+ }
+ catch (...) {
+ Base::Console().Error("Critical error in PropertyPythonObject::restoreObject\n");
+ }
+}
+
void PropertyPythonObject::Save (Base::Writer &writer) const
{
//if (writer.isForceXML()) {
@@ -381,6 +417,88 @@ void PropertyPythonObject::Restore(Base::XMLReader &reader)
}
}
+void PropertyPythonObject::Restore(Base::DocumentReader &reader,XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *ContainerDOM)
+{
+ auto PythonDOM = reader.FindElement(ContainerDOM,"Python");
+ if(PythonDOM){
+ const char* file_cstr = reader.GetAttribute(PythonDOM,"file");
+ if (file_cstr){
+ reader.addFile(file_cstr,this);
+ }else{
+ bool load_json=false;
+ bool load_pickle=false;
+ bool load_failed=false;
+ const char* value_cstr = reader.GetAttribute(PythonDOM,"value");
+ const char* encoded_cstr = reader.GetAttribute(PythonDOM,"encoded");
+ std::string buffer = value_cstr;
+ if (encoded_cstr && strcmp(encoded_cstr,"yes") == 0) {
+ buffer = Base::base64_decode(buffer);
+ }else {
+ buffer = decodeValue(buffer);
+ }
+ Base::PyGILStateLocker lock;
+ try {
+ boost::regex pickle(R"(^\(i(\w+)\n(\w+)\n)");
+ boost::match_results what;
+ std::string::const_iterator start, end;
+ start = buffer.begin();
+ end = buffer.end();
+
+ const char* module_cstr = reader.GetAttribute(PythonDOM,"module");
+ const char* class_cstr = reader.GetAttribute(PythonDOM,"class");
+ const char* json_cstr = reader.GetAttribute(PythonDOM,"json");
+ if (module_cstr && class_cstr) {
+ Py::Module mod(PyImport_ImportModule(module_cstr),true);
+ if (mod.isNull())
+ throw Py::Exception();
+ PyObject* cls = mod.getAttr(class_cstr).ptr();
+ if (!cls) {
+ std::stringstream s;
+ s << "Module " << module_cstr
+ << " has no class " << class_cstr;
+ throw Py::AttributeError(s.str());
+ }
+ if (PyType_Check(cls)) {
+ this->object = PyType_GenericAlloc((PyTypeObject*)cls, 0);
+ }
+ else {
+ throw Py::TypeError("neither class nor type object");
+ }
+ load_json = true;
+ }
+ 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())
+ throw Py::Exception();
+ this->object = PyObject_CallObject(mod.getAttr(type).ptr(), nullptr);
+ load_pickle = true;
+ buffer = std::string(what[2].second, end);
+ }
+ else if (json_cstr) {
+ load_json = true;
+ }
+ }
+ catch (Py::Exception&) {
+ Base::PyException e; // extract the Python error text
+ e.ReportException();
+ this->object = Py::None();
+ load_failed = true;
+ }
+ aboutToSetValue();
+ if (load_json)
+ this->fromString(buffer);
+ else if (load_pickle)
+ this->loadPickle(buffer);
+ else if (!load_failed)
+ Base::Console().Warning("PropertyPythonObject::Restore: unsupported serialisation: %s\n", buffer.c_str());
+ restoreObject(reader,PythonDOM);
+ hasSetValue();
+ }
+ }
+}
+
void PropertyPythonObject::SaveDocFile (Base::Writer &writer) const
{
std::string buffer = this->toString();
diff --git a/src/App/PropertyPythonObject.h b/src/App/PropertyPythonObject.h
index cf1357a234..febdbb255b 100644
--- a/src/App/PropertyPythonObject.h
+++ b/src/App/PropertyPythonObject.h
@@ -60,6 +60,7 @@ public:
void Save (Base::Writer &writer) const override;
/** Use Python's pickle module to restore the object */
void Restore(Base::XMLReader &reader) override;
+ void Restore(Base::DocumentReader &reader,XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *ContainerDOM) override;
void SaveDocFile (Base::Writer &writer) const override;
void RestoreDocFile(Base::Reader &reader) override;
@@ -73,6 +74,7 @@ public:
private:
void saveObject(Base::Writer &writer) const;
void restoreObject(Base::XMLReader &reader);
+ void restoreObject(Base::DocumentReader &reader,XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *ContainerDOM);
std::string encodeValue(const std::string& str) const;
std::string decodeValue(const std::string& str) const;
void loadPickle(const std::string& str);
diff --git a/src/Base/DocumentReader.cpp b/src/Base/DocumentReader.cpp
index 42b1ed7a03..01d18e5275 100644
--- a/src/Base/DocumentReader.cpp
+++ b/src/Base/DocumentReader.cpp
@@ -34,10 +34,10 @@
#endif
#include
-#ifndef _PreComp_
-# include
-# include
-#endif
+//#ifndef _PreComp_
+//# include
+//# include
+//#endif
#ifdef _MSC_VER
# define strdup _strdup
@@ -150,6 +150,24 @@ XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *DocumentReader::FindElement(const cha
return nullptr;
}
+XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *DocumentReader::FindElementByField(
+ XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* Start,
+ const char* TypeEl,const char* field_name,const char* field_value) const
+{
+ if(!TypeEl || !field_name ||!field_value)
+ return nullptr;
+ for (DOMNode *clChild = Start; clChild != nullptr; clChild = clChild->getNextSibling()) {
+ //auto cast = static_cast(clChild);
+ const char* attr = GetAttribute( static_cast(clChild), field_name );
+ if(attr){
+ if( !strcmp( attr, field_value ) ){
+ return static_cast(clChild);;
+ }
+ }
+ }
+ return nullptr;
+}
+
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *DocumentReader::FindElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* Start, const char* Type) const
{
if(!Start || !Type)
diff --git a/src/Base/DocumentReader.h b/src/Base/DocumentReader.h
index 863fa521de..97afbcf906 100644
--- a/src/Base/DocumentReader.h
+++ b/src/Base/DocumentReader.h
@@ -32,6 +32,11 @@
//#include "FileInfo.h"//remplaced:
#include
+#ifndef _PreComp_
+# include
+# include
+#endif
+
namespace zipios {
class ZipInputStream;
}
@@ -62,6 +67,10 @@ public:
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *GetRootElement() const;
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *FindElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* Start, const char* Type) const;
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *FindElement(const char* Type) const;
+
+ XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *FindElementByField(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* Start,
+ const char* TypeEl,const char* field_name, const char* field_value) const;
+
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *FindNextElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *Prev, const char* Type) const;
static long ContentToASCII(const char* Content);
diff --git a/src/Base/Persistence.cpp b/src/Base/Persistence.cpp
index 73e6c2a9f2..de0a1cb240 100644
--- a/src/Base/Persistence.cpp
+++ b/src/Base/Persistence.cpp
@@ -65,12 +65,18 @@ void Persistence::Save (Writer &/*writer*/) const
assert(0);
}
+
void Persistence::Restore(DocumentReader &/*reader*/)
{
+ // you have to implement this method in all descending classes!
+ assert(0);
}
+
void Persistence::Restore(DocumentReader &/*reader*/,XERCES_CPP_NAMESPACE_QUALIFIER DOMElement */*containerEl*/)
{
+ // you have to implement this method in all descending classes!
+ assert(0);
}
void Persistence::Restore(XMLReader &/*reader*/)
diff --git a/src/Mod/Sketcher/Gui/PropertyVisualLayerList.cpp b/src/Mod/Sketcher/Gui/PropertyVisualLayerList.cpp
index 2f35d2b9f2..16536a9b4e 100644
--- a/src/Mod/Sketcher/Gui/PropertyVisualLayerList.cpp
+++ b/src/Mod/Sketcher/Gui/PropertyVisualLayerList.cpp
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include "PropertyVisualLayerList.h"
@@ -91,6 +92,35 @@ void PropertyVisualLayerList::Restore(Base::XMLReader& reader)
setValues(std::move(layers));
}
+void PropertyVisualLayerList::Restore(Base::DocumentReader &reader, XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *containerEl)
+{
+ auto Prop_VisualLayerListDOM = reader.FindElementByField(containerEl,"Property","name","VisualLayerList");
+ if(Prop_VisualLayerListDOM){
+ auto VisualLayerListDOM = reader.FindElement(Prop_VisualLayerListDOM,"VisualLayerList");
+ const char* count_cstr = reader.GetAttribute(VisualLayerListDOM,"count");
+ if(count_cstr){
+ int count = reader.ContentToInt( count_cstr );
+ std::vector layers;
+ layers.reserve(count);
+
+ auto prev_VisualLayerDOM = reader.FindElement(VisualLayerListDOM,"VisualLayer");
+ VisualLayer visualLayer;
+ visualLayer.Restore(reader,prev_VisualLayerDOM);
+ layers.push_back(std::move(visualLayer));
+ for (int i = 1; i < count; i++) {
+ auto VisualLayerDOM_i = reader.FindNextElement(prev_VisualLayerDOM,"VisualLayer");
+ VisualLayer visualLayer;
+ visualLayer.Restore(reader,VisualLayerDOM_i);
+ layers.push_back(std::move(visualLayer));
+ prev_VisualLayerDOM = VisualLayerDOM_i;
+ }
+
+ setValues(std::move(layers));
+ }
+
+ }
+}
+
Property* PropertyVisualLayerList::Copy() const
{
PropertyVisualLayerList* p = new PropertyVisualLayerList();
diff --git a/src/Mod/Sketcher/Gui/PropertyVisualLayerList.h b/src/Mod/Sketcher/Gui/PropertyVisualLayerList.h
index dcbb05c2c8..f03112a8fb 100644
--- a/src/Mod/Sketcher/Gui/PropertyVisualLayerList.h
+++ b/src/Mod/Sketcher/Gui/PropertyVisualLayerList.h
@@ -61,6 +61,7 @@ public:
void Save(Base::Writer& writer) const override;
void Restore(Base::XMLReader& reader) override;
+ void Restore(Base::DocumentReader &reader, XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *containerEl) override;
Property* Copy() const override;
void Paste(const Property& from) override;
diff --git a/src/Mod/Sketcher/Gui/VisualLayer.cpp b/src/Mod/Sketcher/Gui/VisualLayer.cpp
index f44acb4719..b3e58bff59 100644
--- a/src/Mod/Sketcher/Gui/VisualLayer.cpp
+++ b/src/Mod/Sketcher/Gui/VisualLayer.cpp
@@ -22,8 +22,10 @@
#include "PreCompiled.h"
+#include
#include
#include
+#include
#include "VisualLayer.h"
@@ -86,3 +88,21 @@ void VisualLayer::Restore(Base::XMLReader& reader)
linePattern = reader.getAttributeAsUnsigned("linePattern");
lineWidth = reader.getAttributeAsFloat("lineWidth");
}
+
+void VisualLayer::Restore(Base::DocumentReader &reader,XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *ContainerDOM)
+{
+ const char* visible_cstr = reader.GetAttribute(ContainerDOM,"visible");
+ if(visible_cstr){
+ std::string str = visible_cstr;
+ visible = (str == "true");
+
+ const char* linePattern_cstr = reader.GetAttribute(ContainerDOM,"linePattern");
+ const char* lineWidth_cstr = reader.GetAttribute(ContainerDOM,"lineWidth");
+ if(linePattern_cstr && lineWidth_cstr){
+ linePattern = reader.ContentToUnsigned( linePattern_cstr );
+ lineWidth = reader.ContentToUnsigned( lineWidth_cstr );
+ }
+
+
+ }
+}
diff --git a/src/Mod/Sketcher/Gui/VisualLayer.h b/src/Mod/Sketcher/Gui/VisualLayer.h
index 587a835ddd..71dc2ce006 100644
--- a/src/Mod/Sketcher/Gui/VisualLayer.h
+++ b/src/Mod/Sketcher/Gui/VisualLayer.h
@@ -51,6 +51,7 @@ public:
void Save(Base::Writer& /*writer*/) const;
void Restore(Base::XMLReader& /*reader*/);
+ void Restore(Base::DocumentReader &reader, XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *containerEl);
private:
unsigned int linePattern;