/* Copyright 2006-2023 The QElectroTech Team This file is part of QElectroTech. QElectroTech is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. QElectroTech is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QElectroTech. If not, see . */ #include "qetxml.h" #include "NameList/nameslist.h" #include #include #include #include /** @brief QETXML::penToXml Write attribute of a QPen in xml element @param parent_document : parent document for create the QDomElement @param pen : the pen to store @return : A QDomElement with the attribute stored. The tagName of QDomeElement is "pen". */ QDomElement QETXML::penToXml(QDomDocument &parent_document,const QPen& pen) { QDomElement element = parent_document.createElement("pen"); QString style; switch(pen.style()) { case Qt::SolidLine : style = "SolidLine"; break; case Qt::DashLine : style = "DashLine"; break; case Qt::DotLine : style = "DotLine"; break; case Qt::DashDotLine : style = "DashDotLine"; break; case Qt::DashDotDotLine : style = "DashDotDotLine"; break; case Qt::CustomDashLine : style = "CustomDashLine"; break; default : style = "Unknown"; break; } element.setAttribute("style", style); element.setAttribute("color", pen.color().name()); element.setAttribute("widthF", QString::number(pen.widthF())); return element; } /** @brief QETXML::penFromXml Build a QPen from a xml description @param element : The QDomElement that describe the pen @return the created pen. If element is null or tagName isn't "pen" return a default constructed QPen */ QPen QETXML::penFromXml(const QDomElement &element) { QPen pen; if (!(!element.isNull() && element.tagName() == "pen")) { pen.setStyle(Qt::DashLine); return pen; } QString style = element.attribute("style", "DashLine"); if (style == "SolidLine") pen.setStyle(Qt::SolidLine); else if (style == "DashLine") pen.setStyle(Qt::DashLine); else if (style == "DotLine") pen.setStyle(Qt::DotLine); else if (style == "DashDotLine") pen.setStyle(Qt::DashDotLine); else if (style == "DashDotDotLine") pen.setStyle(Qt::DashDotDotLine); else if (style == "CustomDashLine") { pen.setStyle(Qt::CustomDashLine); pen.setDashPattern( QVector() << 10 << 10 ); } else pen.setStyle(Qt::DashLine); pen.setColor(QColor(element.attribute("color", "#000000"))); pen.setWidthF(element.attribute("widthF", "1").toDouble()); return pen; } /** @brief QETXML::brushToXml Write attribute of a QBrush in xml element @param parent_document : parent document for create the QDomElement @param brush : the brush to store @return A QDomElement with the attribute stored. The tagName of QDomeElement is "brush". */ QDomElement QETXML::brushToXml( QDomDocument &parent_document, const QBrush& brush) { QDomElement element = parent_document.createElement("brush"); QString style; switch (brush.style()) { case Qt::NoBrush : style = "NoBrush"; break; case Qt::SolidPattern : style = "SolidPattern"; break; case Qt::Dense1Pattern : style = "Dense1Pattern"; break; case Qt::Dense2Pattern : style = "Dense2Pattern"; break; case Qt::Dense3Pattern : style = "Dense3Pattern"; break; case Qt::Dense4Pattern : style = "Dense4Pattern"; break; case Qt::Dense5Pattern : style = "Dense5Pattern"; break; case Qt::Dense6Pattern : style = "Dense6Pattern"; break; case Qt::Dense7Pattern : style = "Dense7Pattern"; break; case Qt::HorPattern : style = "HorPattern"; break; case Qt::VerPattern : style = "VerPattern"; break; case Qt::CrossPattern : style = "CrossPattern"; break; case Qt::BDiagPattern : style = "BDiagPattern"; break; case Qt::FDiagPattern : style = "FDiagPattern"; break; case Qt::DiagCrossPattern : style = "DiagCrossPattern"; break; default : style = "Unknown"; break; } element.setAttribute("style", style); element.setAttribute("color", brush.color().name()); return element; } /** @brief QETXML::brushFromXml Build a QBrush from a xml description @param element : the QDomElement that describe the pen @return the created brush. If element is null or tagName isn't "brush" return a default constructed QBrush */ QBrush QETXML::brushFromXml(const QDomElement &element) { QBrush brush; if (!(!element.isNull() && element.tagName() == "brush")) return brush; QString style = element.attribute("style", "NoBrush"); if (style == "NoBrush") brush.setStyle(Qt::NoBrush); else if (style == "SolidPattern") brush.setStyle(Qt::SolidPattern); else if (style == "Dense1Pattern") brush.setStyle(Qt::Dense1Pattern); else if (style == "Dense2Pattern") brush.setStyle(Qt::Dense2Pattern); else if (style == "Dense3Pattern") brush.setStyle(Qt::Dense3Pattern); else if (style == "Dense4Pattern") brush.setStyle(Qt::Dense4Pattern); else if (style == "Dense5Pattern") brush.setStyle(Qt::Dense5Pattern); else if (style == "Dense6Pattern") brush.setStyle(Qt::Dense6Pattern); else if (style == "Dense7Pattern") brush.setStyle(Qt::Dense7Pattern); else if (style == "HorPattern") brush.setStyle(Qt::HorPattern); else if (style == "VerPattern") brush.setStyle(Qt::VerPattern); else if (style == "CrossPattern") brush.setStyle(Qt::CrossPattern); else if (style == "BDiagPattern") brush.setStyle(Qt::BDiagPattern); else if (style == "FDiagPattern") brush.setStyle(Qt::FDiagPattern); else if (style == "DiagCrossPattern") brush.setStyle(Qt::DiagCrossPattern); else if (style == "Unknown") brush.setStyle(Qt::NoBrush); brush.setColor(QColor(element.attribute("color", "#000000"))); return brush; } /** @brief QETXML::fileSystemDirToXmlCollectionDir @param document : owner document of returned QDomElement, use to create the QDomElement. @param dir : file system directory to convert to QDomElement directory @param rename : by default the attribute "name" of the returned QDomElement is the same name of @dir but we can override itwith rename @return A file system directory converted to a QDomElement directory ready to be inserted into a XmlElementCollection. If the QDomElement can't be created, return a null QDomElement. */ QDomElement QETXML::fileSystemDirToXmlCollectionDir( QDomDocument &document, const QDir &dir, const QString& rename) { if (!dir.exists()) return QDomElement(); QDomElement dir_element = document.createElement("category"); dir_element.setAttribute("name", rename.isNull()? dir.dirName() : rename); //Get the traduction of this directory QFile qet_dir(dir.filePath("qet_directory")); if (qet_dir.exists() && qet_dir.open( QIODevice::ReadOnly | QIODevice::Text)) { //Get the content of the file QDomDocument trad_document; if (trad_document.setContent(&qet_dir)) { QDomElement root = trad_document.documentElement(); if (root.tagName() == "qet-directory") { NamesList nl; nl.fromXml(root); dir_element.appendChild(nl.toXml(document)); } } qet_dir.close(); } return dir_element; } /** @brief QETXML::fileSystemElementToXmlCollectionElement @param document : owner document of returned QDomElement, use to create the QDomElement. @param file : file system element file to convert to QDomElement; @param rename : by default the attribute "name" of the returned QDomElement is the same name of @file but we can override itwith rename @return A file system element converted to a QDomElement ready to be inserted into a XmlElementCollection If the QDomElement can't be created, return a null QDomElement */ QDomElement QETXML::fileSystemElementToXmlCollectionElement( QDomDocument &document, QFile &file, const QString& rename) { if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) { QDomDocument docu; if (docu.setContent(&file)) { QFileInfo fi(file); QDomElement dom_element = document.createElement("element"); dom_element.setAttribute("name", rename.isEmpty()? fi.fileName() : rename); dom_element.appendChild(docu.documentElement()); file.close(); return dom_element; } else { file.close(); return QDomElement(); } } else return QDomElement(); } /** @brief QETXML::writeXmlFile Export an XML document to an UTF-8 text file indented with 4 spaces, with LF end of lines and no BOM. @param xml_document : An XML document to be exported @param file_path : Path to the file to be written @param error_message : If non-zero, will contain an error message explaining what happened when this function returns false. @return false if an error occurred, true otherwise */ bool QETXML::writeXmlFile( const QDomDocument &xml_document, const QString &file_path, QString *error_message) { QFile file(file_path); // Note: we do not set QIODevice::Text to avoid generating CRLF end of lines bool file_opening = file.open(QIODevice::WriteOnly); if (!file_opening) { if (error_message) { *error_message = QString( QObject::tr( "Impossible d'ouvrir le fichier %1 en écriture, erreur %2 rencontrée.", "error message when attempting to write an XML file") ).arg(file_path).arg(file.error()); } return(false); } QTextStream out(&file); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt 6: remove out.setCodec("UTF-8"); #else #if TODO_LIST #pragma message("@TODO remove code for QT 6 or later") #endif out.setEncoding(QStringConverter::Utf8); #endif out.setGenerateByteOrderMark(false); out << xml_document.toString(4); file.close(); return(true); } /** @brief QETXML::textToDomElement Return a QDomElement, created from document, with tag name tag_name and text value. @param document @param tag_name @param value @return a QDomElement, created from document */ QDomElement QETXML::textToDomElement( QDomDocument &document, const QString& tag_name, const QString& value) { QDomElement element = document.createElement(tag_name); QDomText text = document.createTextNode(value); element.appendChild(text); return element; } /** @brief QETXML::directChild @param element @param tag_name @return All direct child of element with the tag name tag_name */ QVector QETXML::directChild( const QDomElement &element, const QString &tag_name) { QVector return_list; for ( QDomNode node = element.firstChild() ; !node.isNull() ; node = node.nextSibling()) { if (!node.isElement()) continue; QDomElement element = node.toElement(); if (element.isNull() || element.tagName() != tag_name) continue; return_list << element; } return(return_list); } /** @brief QETXML::subChild @param element @param parent_tag_name @param children_tag_name @return When given an xml dom element element, returns a vector of all children dom_elements tagged children_tag_name nested in the parent dom elements tagged parent_tag_name, themselves children of the dom element element. */ QVector QETXML::subChild( const QDomElement &element, const QString parent_tag_name, const QString &children_tag_name) { QVector return_list; for ( QDomNode child = element.firstChild() ; !child.isNull() ; child = child.nextSibling()) { QDomElement parents = child.toElement(); if (parents.isNull() || parents.tagName() != parent_tag_name) continue; for ( QDomNode node_children = parents.firstChild() ; !node_children.isNull() ; node_children = node_children.nextSibling()) { QDomElement n_children = node_children.toElement(); if (!n_children.isNull() && n_children.tagName() == children_tag_name) return_list.append(n_children); } } return(return_list); } /** @brief QETXML::marginsToXml Save a QMargins to xml. the xml tag name is 'margins' @param parent_document @param margins @return */ QDomElement QETXML::marginsToXml(QDomDocument &parent_document, const QMargins &margins) { auto dom_ = parent_document.createElement("margins"); auto text_ = parent_document.createTextNode( QString::number(margins.left()) + QString(";") + QString::number(margins.top()) + QString(";") + QString::number(margins.right()) + QString(";") + QString::number(margins.bottom())); dom_.appendChild(text_); return dom_; } /** @brief QETXML::marginsFromXml @param element @return a QMargins from an xml description. The tag name must ne 'margins' */ QMargins QETXML::marginsFromXml(const QDomElement &element) { if (element.tagName() != "margins") { return QMargins(); } auto margins_ = element.text().split(";"); if (margins_.size() == 4) { return QMargins( margins_.at(0).toInt(), margins_.at(1).toInt(), margins_.at(2).toInt(), margins_.at(3).toInt()); } else { return QMargins(); } } /** @brief QETXML::modelHeaderDataToXml Save to xml element all header data specified by horizontal_section_role and vertical_section_role @param parent_document @param model @param horizontal_section_role : key as header section and value as list of roles to save in xml @param vertical_section_role :key as header section and value as list of roles to save in xml @return */ QDomElement QETXML::modelHeaderDataToXml( QDomDocument &parent_document, const QAbstractItemModel *model, QHash> horizontal_section_role, QHash> vertical_section_role) { auto dom_element = parent_document.createElement("header_data"); auto orientation_ = Qt::Horizontal; auto data_hash = horizontal_section_role; auto meta_enum_ori = QMetaEnum::fromType(); auto meta_enum_role = QMetaEnum::fromType(); //Iterate twice, first for horizontal header and second to vertical header while (true) { for (auto section : data_hash.keys()) { for (auto role : data_hash.value(section)) { auto variant = model->headerData(section, orientation_, role); if (variant.isValid()) { auto dom_data = parent_document.createElement("data"); dom_data.setAttribute("section", QString::number(section)); dom_data.setAttribute("orientation", meta_enum_ori.valueToKey(orientation_)); dom_data.setAttribute("role", meta_enum_role.valueToKey(role)); auto text_node = parent_document.createTextNode(""); if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::ToolTipRole || role == Qt::StatusTipRole || role == Qt::WhatsThisRole) { text_node.setData(variant.toString()); } else if (role == Qt::FontRole) { auto font = variant.value(); text_node.setData(font.toString()); } else if (role == Qt::TextAlignmentRole) { auto me = QMetaEnum::fromType(); text_node.setData(me.valueToKey(variant.toInt())); } dom_data.appendChild(text_node); dom_element.appendChild(dom_data); } } } if(orientation_ == Qt::Vertical) { break; } else { data_hash = vertical_section_role; orientation_ = Qt::Vertical; } } return dom_element; } /** @brief QETXML::modelHeaderDataFromXml Restore from xml modele header data @param element @param model */ void QETXML::modelHeaderDataFromXml( const QDomElement &element, QAbstractItemModel *model) { if (element.tagName() != "header_data") return; auto meta_enum_orientation = QMetaEnum::fromType(); auto meta_enum_role = QMetaEnum::fromType(); for (auto child : QETXML::directChild(element, "data")) { auto section_ = child.attribute("section", "-1").toInt(); auto orientation_ = Qt::Orientation( meta_enum_orientation.keyToValue( child.attribute( "orientation", "Horizontal" ).toStdString().data())); auto role_ = meta_enum_role.keyToValue( child.attribute( "role", "DisplayRole" ).toStdString().data()); auto text_ = child.text(); QVariant data_; if (role_ == Qt::DisplayRole || role_ == Qt::EditRole || role_ == Qt::ToolTipRole || role_ == Qt::StatusTipRole || role_ == Qt::WhatsThisRole) { data_ = text_; } else if (role_ == Qt::FontRole) { QFont font; font.fromString(text_); data_ = font; } else if (role_ == Qt::TextAlignmentRole) { auto me = QMetaEnum::fromType(); data_ = me.keyToValue(text_.toStdString().data()); } model->setHeaderData(section_, orientation_, data_, role_); } } /** * @brief QETXML::findInDomElement * @param dom_elmt * @param tag_name * @return all direct child of dom_elmt with tag name tag_name */ QVector QETXML::findInDomElement(const QDomElement &dom_elmt, const QString &tag_name) { QVector return_list; for (auto node = dom_elmt.firstChild() ; !node.isNull() ; node = node.nextSibling()) { if (!node.isElement()) { continue; } auto element = node.toElement(); if (element.isNull() || element.tagName() != tag_name) { continue; } return_list << element; } return(return_list); } namespace QETXML { /** * @brief boolToString * @param value * @return \p value converted to string */ QString boolToString(bool value) { return value ? QStringLiteral("true") : QStringLiteral("false"); } /** * @brief boolFromString return \p value converted to bool * @param value : value to convert * @param default_value : default value * @param conv_ok : true if \p value is successfully converted * @return */ bool boolFromString(const QString &value, bool default_value, bool *conv_ok) { if (value == QStringLiteral("true") || value == QStringLiteral("1")) { if (conv_ok) { *conv_ok = true; } return true; } if (value == QStringLiteral("false") || value == QStringLiteral("0")) { if (conv_ok) { *conv_ok = true; } return false; } if(conv_ok) { *conv_ok = false; } return default_value; } 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 integer 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 integer 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; } /** * @brief qGraphicsItemPosToXml * Save the pos of a QGraphicsItem into an xml element. * The tag name of the xml element is pos and there is 3 attributes: * x, y, z. * @param item * @param document * @return */ QDomElement qGraphicsItemPosToXml(QGraphicsItem *item, QDomDocument &document) { auto dom_pos = document.createElement(QStringLiteral("pos")); dom_pos.setAttribute(QStringLiteral("x"), QString::number(item->pos().x())); dom_pos.setAttribute(QStringLiteral("y"), QString::number(item->pos().y())); dom_pos.setAttribute(QStringLiteral("z"), QString::number(item->zValue())); return dom_pos; } bool qGraphicsItemPosFromXml(QGraphicsItem *item, const QDomElement &xml_elmt) { if (xml_elmt.tagName() == QLatin1String("pos")) { item->setX(xml_elmt.attribute(QStringLiteral("x"), QStringLiteral("0")).toDouble()); item->setY(xml_elmt.attribute(QStringLiteral("y"), QStringLiteral("0")).toDouble()); item->setZValue(xml_elmt.attribute(QStringLiteral("z"), QStringLiteral("0")).toInt()); return true; } return false; } /** * @brief orientationToAttribute * Write the Qt::orientation has an attribute of @param element. * Attribute name is 'orientation' value is 'horizontal' or 'vertical' * @param orientation * @param element */ void orientationToAttribute(const Qt::Orientation &orientation, QDomElement &element) { element.setAttribute(QStringLiteral("orientation"), orientation == Qt::Horizontal ? QStringLiteral("Horizontal") : QStringLiteral("Vertical")); } /** * @brief orientationFromAttribute * @param element * @param def_value * @return the Qt::Orientation read in @param element. If an error occur * the returned orientation is @param def_value. */ Qt::Orientation orientationFromAttribute(const QDomElement &element, Qt::Orientation def_value) { if (element.hasAttribute(QStringLiteral("orientation"))) { const auto str {element.attribute(QStringLiteral("orientation"))}; if (str == QLatin1String("Horizontal")) return Qt::Horizontal; else if (str == QLatin1String("Vertical")) return Qt::Vertical; } //Error occur during reading, we return the default value return def_value; } void alignmentToAttribute(const Qt::Alignment &alignment, QDomElement &element) { QStringList al; if (alignment &Qt::AlignLeft) al.append(QStringLiteral("Left")); if (alignment &Qt::AlignRight) al.append(QStringLiteral("Right")); if (alignment &Qt::AlignHCenter) al.append(QStringLiteral("HCenter")); if (alignment &Qt::AlignJustify) al.append(QStringLiteral("Justify")); if (alignment &Qt::AlignTop) al.append(QStringLiteral("Top")); if (alignment &Qt::AlignBottom) al.append(QStringLiteral("Bottom")); if (alignment &Qt::AlignBottom) al.append(QStringLiteral("VCenter")); if (alignment &Qt::AlignBaseline) al.append(QStringLiteral("Baseline")); element.setAttribute(QStringLiteral("alignment"),al.join(QStringLiteral(" "))); } /** * @brief alignmentFromAttribute * @param element * @return The alignment read in @param element. If an error * occured the return Qt::alignment contain no set flag. */ Qt::Alignment alignmentFromAttribute(const QDomElement &element) { Qt::Alignment al; if (element.hasAttribute(QStringLiteral("alignment"))) { const auto alignment {element.attribute(QStringLiteral("alignment"))}; if(alignment.contains(QStringLiteral("Left"))) al = al | Qt::AlignLeft; if(alignment.contains(QStringLiteral("Right"))) al = al | Qt::AlignRight; if(alignment.contains(QStringLiteral("HCenter"))) al = al | Qt::AlignHCenter; if(alignment.contains(QStringLiteral("Justify"))) al = al | Qt::AlignJustify; if(alignment.contains(QStringLiteral("Top"))) al = al | Qt::AlignTop; if(alignment.contains(QStringLiteral("Bottom"))) al = al | Qt::AlignBottom; if(alignment.contains(QStringLiteral("VCenter"))) al = al | Qt::AlignVCenter; if(alignment.contains(QStringLiteral("Baseline"))) al = al | Qt::AlignBaseline; } return al; } }