From 1f6545557d4a0485e4465800c529b5ec13cbfe98 Mon Sep 17 00:00:00 2001 From: AgCaliva Date: Tue, 29 Aug 2023 14:41:58 -0300 Subject: [PATCH] Fixed working with tests --- src/App/ExtensionContainer.cpp | 4 +- src/App/PropertyGeo.cpp | 21 ++++ src/App/PropertyGeo.h | 3 +- src/App/PropertyPythonObject.cpp | 118 ++++++++++++++++++ src/App/PropertyPythonObject.h | 2 + src/Base/DocumentReader.cpp | 26 +++- src/Base/DocumentReader.h | 9 ++ src/Base/Persistence.cpp | 6 + .../Sketcher/Gui/PropertyVisualLayerList.cpp | 30 +++++ .../Sketcher/Gui/PropertyVisualLayerList.h | 1 + src/Mod/Sketcher/Gui/VisualLayer.cpp | 20 +++ src/Mod/Sketcher/Gui/VisualLayer.h | 1 + 12 files changed, 234 insertions(+), 7 deletions(-) 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;