DocumentReader implemented for GuiDocument.xml reading.

This commit is contained in:
AgCaliva
2023-06-16 15:36:17 -03:00
parent 52c55f59a8
commit 5f101af3e9
20 changed files with 1053 additions and 304 deletions

View File

@@ -32,6 +32,11 @@
#include "ExtensionContainer.h"
#include <Base/DocumentReader.h>
#ifndef _PreComp_
# include <xercesc/dom/DOM.hpp>
//# include <xercesc/parsers/XercesDOMParser.hpp>
#endif
using namespace App;
@@ -308,7 +313,7 @@ void ExtensionContainer::Restore(Base::XMLReader& reader) {
App::PropertyContainer::Restore(reader);
}
void ExtensionContainer::Restore(Base::DocumentReader& reader,XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *viewProviderEl) {
void ExtensionContainer::Restore(Base::DocumentReader& reader,XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *containerEl) {
//restore dynamic extensions.
//Note 1: The extension element must be read first, before all other object elements. That is
// needed as the element works together with an object element attribute, which would be
@@ -316,7 +321,6 @@ void ExtensionContainer::Restore(Base::DocumentReader& reader,XERCES_CPP_NAMESPA
//Note 2: This must happen before the py object of this container is used, as only in the
// pyobject constructor the extension methods are added to the container.
restoreExtensions(reader,viewProviderEl);
//TODO NOW:
//App::PropertyContainer::Restore(reader);
}
@@ -429,6 +433,80 @@ void ExtensionContainer::restoreExtensions(Base::DocumentReader& reader,XERCES_C
}
}
void ExtensionContainer::restoreExtensions(Base::DocumentReader& reader,XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *containerEl) {
//Dynamic extensions are optional (also because they are introduced late into the document format)
//and hence it is possible that the element does not exist. As we cannot check for the existence of
//an element a object attribute is set if extensions are available. Here we check that
//attribute, and only if it exists the extensions element will be available.
const char* expanded_cstr = reader.GetAttribute(containerEl,"expanded");
if(!expanded_cstr)
return;
auto ExtensionsDOM = reader.FindElement(containerEl,"Extensions");
if(ExtensionsDOM){
const char* cnt_cstr = reader.GetAttribute(ExtensionsDOM,"Count");
if(cnt_cstr){
long Cnt = reader.ContentToInt( cnt_cstr );
auto prev_ExtensionDOM = reader.FindElement(ExtensionsDOM,"Extension");
readExtension(reader,prev_ExtensionDOM);
for (int i=1 ;i<Cnt ;i++) {
auto ExtensionDOM_i = reader.FindNextElement(prev_ExtensionDOM,"Extension");
readExtension(reader,ExtensionDOM_i);
prev_ExtensionDOM = ExtensionDOM_i;
}
}
}
}
void ExtensionContainer::readExtension(Base::DocumentReader &reader,XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *ExtensionDOM){
const char* type_cstr = reader.GetAttribute(ExtensionDOM,"type");
const char* name_cstr = reader.GetAttribute(ExtensionDOM,"name");
try {
App::Extension* ext = getExtension(name_cstr);
if(!ext) {
//get the extension type asked for
Base::Type extension = Base::Type::fromName(type_cstr);
if (extension.isBad() || !extension.isDerivedFrom(App::Extension::getExtensionClassTypeId())) {
std::stringstream str;
str << "No extension found of type '" << type_cstr << "'" << std::ends;
throw Base::TypeError(str.str());
}
//register the extension
ext = static_cast<App::Extension*>(extension.createInstance());
//check if this really is a python extension!
if (!ext->isPythonExtension()) {
delete ext;
std::stringstream str;
str << "Extension is not a python addable version: '" << type_cstr << "'" << std::ends;
throw Base::TypeError(str.str());
}
ext->initExtension(this);
if( strcmp(ext->getExtensionTypeId().getName(), type_cstr) == 0 )
ext->extensionRestore(reader);
}
}
catch (const Base::XMLParseException&) {
throw; // re-throw
}
catch (const Base::Exception &e) {
Base::Console().Error("%s\n", e.what());
}
catch (const std::exception &e) {
Base::Console().Error("%s\n", e.what());
}
catch (const char* e) {
Base::Console().Error("%s\n", e);
}
#ifndef FC_DEBUG
catch (...) {
Base::Console().Error("ExtensionContainer::Restore: Unknown C++ exception thrown\n");
}
#endif
}
void ExtensionContainer::restoreExtensions(Base::XMLReader& reader) {
//Dynamic extensions are optional (also because they are introduced late into the document format)
@@ -508,6 +586,20 @@ void ExtensionContainer::handleChangedPropertyName(Base::XMLReader &reader, cons
PropertyContainer::handleChangedPropertyName(reader, TypeName, PropName);
}
void ExtensionContainer::handleChangedPropertyName(Base::DocumentReader &reader, const char * TypeName, const char *PropName)
{
//inform all extensions about changed property name. This includes all properties from the
//extended object (this) as well as all extension properties
for(const auto& entry : _extensions) {
bool handled = entry.second->extensionHandleChangedPropertyName(reader, TypeName, PropName);
if(handled)
return; // one property change needs only be handled once
}
PropertyContainer::handleChangedPropertyName(reader, TypeName, PropName);
}
void ExtensionContainer::handleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, Property * prop)
{
//inform all extensions about changed property type. This includes all properties from the
@@ -521,3 +613,17 @@ void ExtensionContainer::handleChangedPropertyType(Base::XMLReader &reader, cons
PropertyContainer::handleChangedPropertyType(reader, TypeName, prop);
}
void ExtensionContainer::handleChangedPropertyType(Base::DocumentReader &reader, const char * TypeName, Property * prop)
{
//inform all extensions about changed property type. This includes all properties from the
//extended object (this) as well as all extension properties
for(const auto& entry : _extensions) {
bool handled = entry.second->extensionHandleChangedPropertyType(reader, TypeName, prop);
if(handled)
return; // one property change needs only be handled once
}
PropertyContainer::handleChangedPropertyType(reader, TypeName, prop);
}