mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	XFA: template tree definition
This commit is contained in:
		| @@ -1486,6 +1486,13 @@ void XFACodeGenerator::loadClasses(const QDomDocument& document) | ||||
|         // Class name | ||||
|         myClass.className = element.attribute("name"); | ||||
|  | ||||
|         QDomElement valueElement = element.firstChildElement("value"); | ||||
|         if (!valueElement.isNull()) | ||||
|         { | ||||
|             QString valueType = valueElement.attribute("type"); | ||||
|             myClass.valueType = createType("node_value", "nodeValue", valueType); | ||||
|         } | ||||
|  | ||||
|         // Attributes | ||||
|         QDomNodeList attributes = element.elementsByTagName("property"); | ||||
|         const int attributeCount = attributes.size(); | ||||
| @@ -1505,6 +1512,24 @@ void XFACodeGenerator::loadClasses(const QDomDocument& document) | ||||
|             myClass.attributes.emplace_back(std::move(attribute)); | ||||
|         } | ||||
|  | ||||
|         // Subnodes | ||||
|         QDomNodeList subnodes = element.elementsByTagName("item"); | ||||
|         const int subnodeCount = subnodes.size(); | ||||
|         for (int ai = 0; ai < subnodeCount; ++ai) | ||||
|         { | ||||
|             QDomElement subnodeElement = subnodes.item(ai).toElement(); | ||||
|             QString className = subnodeElement.attribute("class"); | ||||
|             QString min = subnodeElement.attribute("min"); | ||||
|             QString max = subnodeElement.attribute("max"); | ||||
|  | ||||
|             Subnode subnode; | ||||
|             subnode.subnodeName = std::move(className); | ||||
|             subnode.min = min.toInt(); | ||||
|             subnode.max = (max == "n") ? std::numeric_limits<int>::max() : max.toInt(); | ||||
|  | ||||
|             myClass.subnodes.emplace_back(std::move(subnode)); | ||||
|         } | ||||
|  | ||||
|         m_classes.emplace_back(std::move(myClass)); | ||||
|     } | ||||
| } | ||||
| @@ -1555,11 +1580,13 @@ const XFACodeGenerator::Type* XFACodeGenerator::createType(QString id, QString n | ||||
|             QString finalTypeName = typeName; | ||||
|  | ||||
|             int i = 1; | ||||
|             while (m_types.count(finalTypeName)) | ||||
|             while (m_usedTypes.count(finalTypeName)) | ||||
|             { | ||||
|                 finalTypeName = typeName + QString::number(i++); | ||||
|             } | ||||
|  | ||||
|             m_usedTypes.insert(finalTypeName); | ||||
|  | ||||
|             QString enumValues = enumValuesString.remove(QChar::Space); | ||||
|             type.enumValues = enumValues.split("|"); | ||||
|  | ||||
| @@ -1585,6 +1612,14 @@ QString XFACodeGenerator::generateSource() const | ||||
|         stream << "namespace xfa" << Qt::endl; | ||||
|         stream << "{" << Qt::endl << Qt::endl; | ||||
|  | ||||
|         // Forward declarations | ||||
|         for (const Class& myClass : m_classes) | ||||
|         { | ||||
|             stream << QString("class XFA_%1;").arg(myClass.className) << Qt::endl; | ||||
|         } | ||||
|  | ||||
|         stream << Qt::endl; | ||||
|  | ||||
|         stream << "class XFA_BaseNode : public XFA_AbstractNode" << Qt::endl; | ||||
|         stream << "{" << Qt::endl; | ||||
|         stream << "public:" << Qt::endl; | ||||
| @@ -1630,12 +1665,55 @@ QString XFACodeGenerator::generateSource() const | ||||
|                 attributeGetters << attributeGetter; | ||||
|             } | ||||
|  | ||||
|             stream << Qt::endl; | ||||
|  | ||||
|             QStringList subnodeGetters; | ||||
|             QStringList subnodeDeclarations; | ||||
|             for (const Subnode& subnode : myClass.subnodes) | ||||
|             { | ||||
|                 if (subnode.max == 1) | ||||
|                 { | ||||
|                     QString subnodeFieldName = QString("m_%1").arg(subnode.subnodeName); | ||||
|                     QString subnodeTypeName = QString("XFA_%1").arg(subnode.subnodeName); | ||||
|                     QString subnodeGetterName = subnode.subnodeName; | ||||
|                     subnodeGetterName[0] = subnodeGetterName.front().toUpper(); | ||||
|                     QString subnodeDeclaration = QString("    XFA_Node<%1> %2;").arg(subnodeTypeName, subnodeFieldName); | ||||
|                     QString subnodeGetter = QString("    const %1* get%2() const {  return %3.getValue(); }").arg(subnodeTypeName, subnodeGetterName, subnodeFieldName); | ||||
|                     subnodeDeclarations << subnodeDeclaration; | ||||
|                     subnodeGetters << subnodeGetter; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     QString subnodeFieldName = QString("m_%1").arg(subnode.subnodeName); | ||||
|                     QString subnodeTypeName = QString("std::vector<XFA_Node<XFA_%1>>").arg(subnode.subnodeName); | ||||
|                     QString subnodeGetterName = subnode.subnodeName; | ||||
|                     subnodeGetterName[0] = subnodeGetterName.front().toUpper(); | ||||
|                     QString subnodeDeclaration = QString("    %1 %2;").arg(subnodeTypeName, subnodeFieldName); | ||||
|                     QString subnodeGetter = QString("    const %1& get%2() const {  return %3; }").arg(subnodeTypeName, subnodeGetterName, subnodeFieldName); | ||||
|                     subnodeDeclarations << subnodeDeclaration; | ||||
|                     subnodeGetters << subnodeGetter; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             for (const QString& getter : attributeGetters) | ||||
|             { | ||||
|                 stream << getter << Qt::endl; | ||||
|             } | ||||
|  | ||||
|             stream << Qt::endl; | ||||
|  | ||||
|             for (const QString& getter : subnodeGetters) | ||||
|             { | ||||
|                 stream << getter << Qt::endl; | ||||
|             } | ||||
|  | ||||
|             stream << Qt::endl; | ||||
|  | ||||
|             if (myClass.valueType) | ||||
|             { | ||||
|                 stream << QString("    const %1* getNodeValue() const {  return m_nodeValue.getValue(); }").arg(myClass.valueType->typeName) << Qt::endl << Qt::endl; | ||||
|             } | ||||
|  | ||||
|             stream << "private:" << Qt::endl; | ||||
|             stream << "    /* properties */" << Qt::endl; | ||||
|  | ||||
| @@ -1646,6 +1724,19 @@ QString XFACodeGenerator::generateSource() const | ||||
|  | ||||
|             stream << Qt::endl; | ||||
|  | ||||
|             stream << "    /* subnodes */" << Qt::endl; | ||||
|  | ||||
|             for (const QString& getter : subnodeDeclarations) | ||||
|             { | ||||
|                 stream << getter << Qt::endl; | ||||
|             } | ||||
|  | ||||
|             if (myClass.valueType) | ||||
|             { | ||||
|                 stream << Qt::endl; | ||||
|                 stream << QString("    XFA_Value<%1> m_nodeValue;").arg(myClass.valueType->typeName) << Qt::endl; | ||||
|             } | ||||
|  | ||||
|             stream << "};" << Qt::endl << Qt::endl; | ||||
|         } | ||||
|  | ||||
| @@ -1668,6 +1759,9 @@ QString XFACodeGenerator::getEnumValueName(QString enumName) const | ||||
|         } | ||||
|  | ||||
|         enumName.replace("-", "_"); | ||||
|         enumName.replace('\\', "Backslash"); | ||||
|         enumName.replace('/', "Slash"); | ||||
|         enumName.replace('.', "_"); | ||||
|     } | ||||
|  | ||||
|     return enumName; | ||||
|   | ||||
| @@ -26,6 +26,8 @@ | ||||
| #include <QObjectList> | ||||
| #include <QComboBox> | ||||
|  | ||||
| #include <set> | ||||
|  | ||||
| namespace codegen | ||||
| { | ||||
|  | ||||
| @@ -469,11 +471,20 @@ private: | ||||
|         QString defaultValue; | ||||
|     }; | ||||
|  | ||||
|     struct Subnode | ||||
|     { | ||||
|         QString subnodeName; | ||||
|         int min = 0; | ||||
|         int max = 0; | ||||
|     }; | ||||
|  | ||||
|     struct Class | ||||
|     { | ||||
|         QString className; | ||||
|         QString valueType; | ||||
|         const Type* valueType = nullptr; | ||||
|         QString nodeValue; | ||||
|         std::vector<Attribute> attributes; | ||||
|         std::vector<Subnode> subnodes; | ||||
|     }; | ||||
|  | ||||
|     void loadClasses(const QDomDocument& document); | ||||
| @@ -485,6 +496,7 @@ private: | ||||
|  | ||||
|     std::vector<Class> m_classes; | ||||
|     std::map<QString, Type> m_types; | ||||
|     std::set<QString> m_usedTypes; | ||||
| }; | ||||
|  | ||||
| }   // namespace codegen | ||||
|   | ||||
		Reference in New Issue
	
	Block a user