XFA: attribute parsing

This commit is contained in:
Jakub Melka 2021-10-31 18:04:00 +01:00
parent 588526df6f
commit e3c2df6314
4 changed files with 4362 additions and 111 deletions

View File

@ -1623,6 +1623,7 @@ QString XFACodeGenerator::generateSource() const
stream << "class XFA_BaseNode : public XFA_AbstractNode" << Qt::endl;
stream << "{" << Qt::endl;
stream << "public:" << Qt::endl;
stream << " using XFA_AbstractNode::parseAttribute;" << Qt::endl;
stream << Qt::endl;
@ -1644,6 +1645,29 @@ QString XFACodeGenerator::generateSource() const
stream << " };" << Qt::endl << Qt::endl;
}
for (const auto& typeItem : m_types)
{
const Type& type = typeItem.second;
if (type.enumValues.isEmpty())
{
continue;
}
stream << QString(" static void parseAttribute(const QDomElement& element, QString attributeFieldName, XFA_Attribute<%1>& attribute, QString defaultValue)").arg(type.typeName) << Qt::endl;
stream << QString(" {") << Qt::endl;
stream << QString(" constexpr std::array enumValues = {") << Qt::endl;
for (const QString& enumValue : type.enumValues)
{
QString adjustedEnumValue = enumValue;
adjustedEnumValue.replace("\\", "\\\\");
stream << QString(" std::make_pair(%1::%2, \"%3\"),").arg(type.typeName, getEnumValueName(enumValue), adjustedEnumValue) << Qt::endl;
}
stream << QString(" };") << Qt::endl;
stream << QString(" parseEnumAttribute(element, attributeFieldName, attribute, defaultValue, enumValues);") << Qt::endl;
stream << QString(" }") << Qt::endl << Qt::endl;
}
stream << "};" << Qt::endl << Qt::endl;
for (const Class& myClass : m_classes)
@ -1714,6 +1738,10 @@ QString XFACodeGenerator::generateSource() const
stream << QString(" const %1* getNodeValue() const { return m_nodeValue.getValue(); }").arg(myClass.valueType->typeName) << Qt::endl << Qt::endl;
}
stream << QString(" static std::optional<XFA_%1> parse(const QDomElement& element);").arg(myClass.className) << Qt::endl;
stream << Qt::endl;
stream << "private:" << Qt::endl;
stream << " /* properties */" << Qt::endl;
@ -1738,6 +1766,37 @@ QString XFACodeGenerator::generateSource() const
}
stream << "};" << Qt::endl << Qt::endl;
// Class loader
stream << QString("std::optional<XFA_%1> XFA_%1::parse(const QDomElement& element)").arg(myClass.className) << Qt::endl;
stream << "{" << Qt::endl;
stream << " if (element.isNull())" << Qt::endl << " {" << Qt::endl << " return std::nullopt;" << Qt::endl << " }" << Qt::endl << Qt::endl;
stream << QString(" XFA_%1 myClass;").arg(myClass.className) << Qt::endl << Qt::endl;
// Load attributes
stream << " // load attributes" << Qt::endl;
for (const Attribute& attribute : myClass.attributes)
{
QString attributeFieldName = QString("m_%1").arg(attribute.attributeName);
QString adjustedDefaultValue = attribute.defaultValue;
adjustedDefaultValue.replace("\\", "\\\\");
stream << QString(" parseAttribute(element, \"%1\", myClass.%2, \"%3\");").arg(attribute.attributeName, attributeFieldName, adjustedDefaultValue) << Qt::endl;
}
stream << Qt::endl;
// Load subitems
stream << " // load items" << Qt::endl;
for (const Subnode& subnode : myClass.subnodes)
{
QString subnodeFieldName = QString("m_%1").arg(subnode.subnodeName);
stream << QString(" parseItem(element, \"%1\", myClass.%2);").arg(subnode.subnodeName, subnodeFieldName) << Qt::endl;
}
stream << " return myClass;" << Qt::endl;
stream << "}" << Qt::endl;
stream << Qt::endl << Qt::endl;
}
stream << "} // namespace xfa" << Qt::endl;

View File

@ -15,7 +15,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
QT += gui widgets
QT += gui widgets xml
TARGET = Pdf4QtLib
TEMPLATE = lib

File diff suppressed because it is too large Load Diff

View File

@ -20,128 +20,21 @@
#include "pdfglobal.h"
#include <optional>
#include <memory>
namespace pdf
{
namespace xfa
{
struct XFA_InplaceTag;
struct XFA_SharedMemoryTag;
template<typename Value, typename Tag>
class PDFXFAValueHolder
{
public:
constexpr inline bool hasValue() const { return false; }
constexpr const Value* getValue() const { return nullptr; }
};
template<typename Value>
class PDFXFAValueHolder<Value, XFA_InplaceTag>
{
public:
inline constexpr PDFXFAValueHolder(std::optional<Value> value) :
m_value(std::move(value))
{
}
constexpr inline bool hasValue() const { return m_value.has_value(); }
constexpr const Value* getValue() const { return m_value.has_value() ? &m_value.value() : nullptr; }
private:
std::optional<Value> m_value;
};
template<typename Value>
class PDFXFAValueHolder<Value, XFA_SharedMemoryTag>
{
public:
inline constexpr PDFXFAValueHolder(std::optional<Value> value) :
m_value()
{
if (value)
{
m_value = std::make_shared(std::move(*value));
}
}
constexpr inline bool hasValue() const { return m_value; }
constexpr const Value* getValue() const { return m_value.get(); }
private:
std::shared_ptr<Value> m_value;
};
template<typename Value>
using XFA_Attribute = PDFXFAValueHolder<Value, XFA_InplaceTag>;
template<typename Value>
using XFA_Node = PDFXFAValueHolder<Value, XFA_SharedMemoryTag>;
template<typename Value>
using XFA_Value = PDFXFAValueHolder<Value, XFA_InplaceTag>;
class XFA_Measurement
{
public:
enum Type
{
in,
cm,
mm,
pt,
em,
percent
};
constexpr inline XFA_Measurement() :
m_value(0.0),
m_type(in)
{
}
constexpr inline XFA_Measurement(PDFReal value, Type type) :
m_value(value),
m_type(type)
{
}
constexpr inline XFA_Measurement(PDFReal value) :
m_value(value),
m_type(in)
{
}
constexpr PDFReal getValue() const { return m_value; }
constexpr Type getType() const { return m_type; }
private:
PDFReal m_value;
Type m_type;
};
class XFA_AbstractNode
{
public:
constexpr inline XFA_AbstractNode() = default;
virtual ~XFA_AbstractNode();
};
} // namespace xfa
class PDFXFAEngineImpl;
class PDFXFAEngine
{
public:
PDFXFAEngine();
~PDFXFAEngine();
private:
std::unique_ptr<PDFXFAEngineImpl> m_impl;
};
/* START GENERATED CODE */