diff --git a/sources/qetxml.cpp b/sources/qetxml.cpp index 58e8255c3..42df0846d 100644 --- a/sources/qetxml.cpp +++ b/sources/qetxml.cpp @@ -581,3 +581,299 @@ QVector QETXML::findInDomElement(const QDomElement &dom_elmt, const } return(return_list); } + +namespace QETXML { + +PropertyFlags debugReadXml(PropertyFlags flag, const QDomElement &e, const QString& attribute_name, const QString& attr, const QString& type) +{ + if (flag == QETXML::PropertyFlags::NoValidConversion) + qDebug() << "\t\t\t" << "Tagname: " << e.tagName() << ". " << "No valid Conversion: " << attribute_name << ". type: " << type << ". value: " << attr; + + return flag; +} + +QDomElement createXmlProperty(const QString& name, const QString value) { + QDomDocument doc; + QDomElement p = doc.createElement("property"); + p.setAttribute("name", name); + p.setAttribute("type", stringS); + p.setAttribute("value", value); + return p; +} + +QDomElement createXmlProperty(const QString& name, const char* value) { + QDomDocument doc; + QDomElement p = doc.createElement("property"); + p.setAttribute("name", name); + p.setAttribute("type", stringS); + p.setAttribute("value", value); + return p; +} + +/*! + * \brief propertyInteger + * Reads an interger from the XML element. + * \param e DomElement which contains the property attribute + * \param attribute_name Name of the attribute + * \param entier Return value if success + * \return True if reading an integer was successful, else False. If the attribute was not found, + * \p entier is not valid and the return value is False + */ +QDomElement createXmlProperty(const QString& name, const int value) { + QDomDocument doc; + QDomElement p = doc.createElement("property"); + p.setAttribute("name", name); + p.setAttribute("type", integerS); + p.setAttribute("value", QString::number(value)); + return p; +} + +QDomElement createXmlProperty(const QString& name, const double value) { + QDomDocument doc; + QDomElement p = doc.createElement("property"); + p.setAttribute("name", name); + p.setAttribute("type", doubleS); + p.setAttribute("value", QString::number(value)); + return p; +} + +QDomElement createXmlProperty(const QString& name, const bool value) { + QDomDocument doc; + QDomElement p = doc.createElement("property"); + p.setAttribute("name", name); + p.setAttribute("type", boolS); + p.setAttribute("value", QString::number(value)); + return p; +} + +QDomElement createXmlProperty(const QString& name, const QUuid value) { + QDomDocument doc; + QDomElement p = doc.createElement("property"); + p.setAttribute("name", name); + p.setAttribute("type", uuidS); + p.setAttribute("value", value.toString()); + return p; +} + +QDomElement createXmlProperty(const QString& name, const QColor value) { + QDomDocument doc; + QDomElement p = doc.createElement("property"); + p.setAttribute("name", name); + p.setAttribute("type", colorS); + p.setAttribute("value", value.name()); + return p; +} + +/*! + * \brief PropertiesInterface::propertyInteger + * Reads an interger from the XML element. + * \param e DomElement which contains the property attribute + * \param attribute_name Name of the attribute + * \param entier Return value if success + * \return True if reading an integer was successful, else False. If the attribute was not found, + * \p entier is not valid and the return value is False + */ +PropertyFlags propertyInteger(const QDomElement &e, const QString& attribute_name, int* entier) { + + QString attr; + + if (!attribute(e, attribute_name, integerS, &attr)) { + return PropertyFlags::NotFound; + } + + return debugReadXml(propertyInteger(attr, entier), e, attribute_name, attr, integerS); +} + +PropertyFlags propertyInteger(const QString& value, int* entier) { + // verifie la validite de l'attribut + bool ok; + int tmp = value.toInt(&ok); + if (!ok) { + return QETXML::PropertyFlags::NoValidConversion; + } + + if (entier != nullptr) + *entier = tmp; + + return PropertyFlags::Success; +} + +PropertyFlags propertyDouble(const QDomElement &e, const QString& attribute_name, double* reel) { + + QString attr; + + if (!attribute(e, attribute_name, doubleS, &attr)) { + return PropertyFlags::NotFound; + } + + return debugReadXml(propertyDouble(attr, reel), e, attribute_name, attr, doubleS); +} + +PropertyFlags propertyDouble(const QString& value, double* reel) +{ + // verifie la validite de l'attribut + bool ok; + double tmp = value.toDouble(&ok); + if (!ok) { + return QETXML::PropertyFlags::NoValidConversion; + } + + if (reel != nullptr) + *reel = tmp; + + return PropertyFlags::Success; +} + +PropertyFlags propertyBool(const QDomElement &e, const QString& attribute_name, bool* boolean) { + + QString attr; + + if (!attribute(e, attribute_name, boolS, &attr)) { + return PropertyFlags::NotFound; + } + + return debugReadXml(propertyBool(attr, boolean), e, attribute_name, attr, boolS); +} + +PropertyFlags propertyBool(const QString& value, bool* boolean) +{ + // verifie la validite de l'attribut + bool ok; + bool tmp = value.toInt(&ok); + if (!ok) { + if (value == "true" || value == "1") + tmp = true; + else if (value == "false" || value == "0") + tmp = false; + else { + return QETXML::PropertyFlags::NoValidConversion; + } + } + + if (boolean != nullptr) + *boolean = tmp; + + return PropertyFlags::Success; +} + +PropertyFlags propertyColor(const QDomElement &e, const QString& attribute_name, QColor* color) { + + QString attr; + + if (!attribute(e, attribute_name, colorS, &attr)) { + return PropertyFlags::NotFound; + } + + return debugReadXml(propertyColor(attr, color), e, attribute_name, attr, colorS); +} + +PropertyFlags propertyColor(const QString& value, QColor* color) +{ + // verifie la validite de l'attribut + QColor tmp = QColor(value); + if (!tmp.isValid()) { + return QETXML::PropertyFlags::NoValidConversion; + } + + if (color != nullptr) + *color = tmp; + + return PropertyFlags::Success; +} + +PropertyFlags propertyUuid(const QDomElement &e, const QString& attribute_name, QUuid* uuid) { + QString attr; + + if (!attribute(e, attribute_name, uuidS, &attr)) { + return PropertyFlags::NotFound; + } + + return debugReadXml(propertyUuid(attr, uuid), e, attribute_name, attr, uuidS); +} + +PropertyFlags propertyUuid(const QString& value, QUuid* uuid) +{ + if (QUuid(value).isNull()){ + return QETXML::PropertyFlags::NoValidConversion; + } + + + if (uuid != nullptr) + *uuid = QUuid(value); + + return PropertyFlags::Success; +} + +PropertyFlags propertyString(const QDomElement& e, const QString& attribute_name, QString* string) { + + QString attr; + if (!attribute(e, attribute_name, stringS, &attr)) { + return PropertyFlags::NotFound; + } + + // verifie la validite de l'attribut + if (string != nullptr) + *string = attr; + + return PropertyFlags::Success; +} + +QDomElement property(const QDomElement& e, const QString& name) { + for (int i=0; i < e.childNodes().count(); i++) { + QDomElement child = e.childNodes().at(i).toElement(); + if (!validXmlProperty(child)) + continue; // there might also non property childs + + if (child.attribute("name") == name) + return child; + } + return QDomElement(); +} + +/*! + * \brief PropertiesInterface::attribute + * Returns the property with the name \p attribute_name and type \p type + * \param e Xml element which contains the property + * \param attribute_name + * \param type Type of the property + * \param attr + * \return + */ +bool attribute(const QDomElement& e, const QString& attribute_name, const QString& type, QString* attr) { + QDomElement p = property(e, attribute_name); + if (p.isNull()) { + // check if legacy property is available, + // where the property is inside the element as attribute + if (!e.hasAttribute(attribute_name)) { + qDebug() << "\t\t\t" << "Tagname: " << e.tagName() << ". " << "Property " << attribute_name << "is not available"; + return false; + } + + *attr = e.attribute(attribute_name); + + } else { + if (p.attribute("type") != type) { + qDebug() << "\t\t\t" << "Tagname: " << e.tagName() << ", Property: " << attribute_name << "(" << p.attribute("type") << ") has not type: " << type; + return false; + } + + *attr = p.attribute("value"); + + } + return true; +} + +bool validXmlProperty(const QDomElement& e) { + if (!e.hasAttribute("name")) + return false; + + if (!e.hasAttribute("type")) + return false; + + if (!e.hasAttribute("value")) + return false; + + return true; +} + +} diff --git a/sources/qetxml.h b/sources/qetxml.h index 0c4ae7e95..6c84c74e9 100644 --- a/sources/qetxml.h +++ b/sources/qetxml.h @@ -89,6 +89,54 @@ namespace QETXML QVector findInDomElement(const QDomElement &dom_elmt, const QString &tag_name); + + const QString integerS = "int"; + const QString doubleS = "double"; + const QString boolS = "bool"; + const QString stringS = "string"; + const QString uuidS = "uuid"; + const QString colorS = "color"; + + enum PropertyFlags { + Success = 0, + NotFound = 1, + NoValidConversion = 2, + // = 4 + }; + + /*! + * Use this functions to add properties to the xml document + */ + QDomElement createXmlProperty(const QString& name, const QString value); + QDomElement createXmlProperty(const QString& name, const char* value); + QDomElement createXmlProperty(const QString& name, const int value); + QDomElement createXmlProperty(const QString& name, const double value); + QDomElement createXmlProperty(const QString& name, const bool value); + QDomElement createXmlProperty(const QString& name, const QUuid value); + QDomElement createXmlProperty(const QString& name, const QColor value); + + PropertyFlags propertyInteger(const QString& value, int* entry = nullptr); + PropertyFlags propertyInteger(const QDomElement &e, const QString& attribute_name, int *entier = nullptr); + PropertyFlags propertyDouble(const QString& value, double* entry = nullptr); + PropertyFlags propertyDouble(const QDomElement &e, const QString& attribute_name, double *reel = nullptr); + PropertyFlags propertyString(const QDomElement& e, const QString& attribute_name, QString* string = nullptr); + PropertyFlags propertyBool(const QString& value, bool* entry = nullptr); + PropertyFlags propertyBool(const QDomElement &e, const QString& attribute_name, bool* boolean = nullptr); + PropertyFlags propertyUuid(const QString& value, QUuid* entry = nullptr); + PropertyFlags propertyUuid(const QDomElement &e, const QString& attribute_name, QUuid* uuid = nullptr); + PropertyFlags propertyColor(const QString& value, QColor* entry = nullptr); + PropertyFlags propertyColor(const QDomElement &e, const QString& attribute_name, QColor* color = nullptr); + + QDomElement property(const QDomElement& e, const QString& name); + bool attribute(const QDomElement& e, const QString& attribute_name, const QString& type, QString* attr); + + /*! + * \brief PropertiesInterface::validXmlProperty + * Check if the Xml element contains the needed fields + * \param e Xml Property + * \return True if name, type, value attribute are available, else false + */ + bool validXmlProperty(const QDomElement& e); } #endif // QETXML_H