diff --git a/sources/QetGraphicsItemModeler/qetgraphicshandleritem.h b/sources/QetGraphicsItemModeler/qetgraphicshandleritem.h index b482ebbb7..614b31534 100644 --- a/sources/QetGraphicsItemModeler/qetgraphicshandleritem.h +++ b/sources/QetGraphicsItemModeler/qetgraphicshandleritem.h @@ -53,7 +53,7 @@ class QetGraphicsHandlerItem : public QGraphicsItem QRectF m_handler_rect, m_br; qreal m_size; - QColor m_color; + QColor m_color{Qt::black}; QPen m_pen; public: diff --git a/sources/borderproperties.cpp b/sources/borderproperties.cpp index 1a4a98b61..a65071fc2 100644 --- a/sources/borderproperties.cpp +++ b/sources/borderproperties.cpp @@ -16,6 +16,7 @@ along with QElectroTech. If not, see . */ #include "borderproperties.h" +#include "qetxml.h" /** @brief BorderProperties::BorderProperties @@ -25,22 +26,14 @@ Initializes a BorderProperties object with the following default properties: - 17 columns of 60.0 px wide by 20.0px high - - 8 lines of 80.0 px high by 20.0px wide + - 8 lines of 80.0 px high by 20.0px wide \~French Initialise un objet BorderProperties avec les proprietes par defaut suivantes : - 17 colonnes affichees de 60.0 px de large pour 20.0px de haut - - 8 lignes affichees de 80.0 px de haut pour 20.0px de large + - 8 lignes affichees de 80.0 px de haut pour 20.0px de large */ -BorderProperties::BorderProperties() : - columns_count(17), - columns_width(60.0), - columns_header_height(20.0), - display_columns(true), - rows_count(8), - rows_height(80.0), - rows_header_width(20.0), - display_rows(true) +BorderProperties::BorderProperties(): PropertiesInterface("border") { } @@ -88,7 +81,7 @@ bool BorderProperties::operator!=(const BorderProperties &bp) { } /** - @brief BorderProperties::toXml + @brief BorderProperties::toXmlPriv Exports dimensions as XML attributes added to element e. \~French Exporte les dimensions sous formes d'attributs XML ajoutes a l'element e. @@ -96,18 +89,17 @@ bool BorderProperties::operator!=(const BorderProperties &bp) { XML element to which attributes will be added \~French Element XML auquel seront ajoutes des attributs */ -void BorderProperties::toXml(QDomElement &e) const -{ - e.setAttribute("cols", columns_count); - e.setAttribute("colsize", QString("%1").arg(columns_width)); - e.setAttribute("rows", rows_count); - e.setAttribute("rowsize", QString("%1").arg(rows_height)); - e.setAttribute("displaycols", display_columns ? "true" : "false"); - e.setAttribute("displayrows", display_rows ? "true" : "false"); +void BorderProperties::toXmlPriv(QDomElement& e) const { + e.setAttribute("cols", columns_count); + e.setAttribute("colsize", QString("%1").arg(columns_width)); + e.setAttribute("rows", rows_count); + e.setAttribute("rowsize", QString("%1").arg(rows_height)); + e.setAttribute("displaycols", display_columns ? "true" : "false"); + e.setAttribute("displayrows", display_rows ? "true" : "false"); } -/** - @brief BorderProperties::fromXml +/*!RETURNS True + @brief BorderProperties::fromXmlPriv Import dimensions from XML attributes of element e \~French Importe les dimensions a partir des attributs XML de l'element e @@ -115,13 +107,29 @@ void BorderProperties::toXml(QDomElement &e) const XML element whose attributes will be read \~French Element XML dont les attributs seront lus */ -void BorderProperties::fromXml(QDomElement &e) { - if (e.hasAttribute("cols")) columns_count = e.attribute("cols").toInt(); - if (e.hasAttribute("colsize")) columns_width = e.attribute("colsize").toInt(); - if (e.hasAttribute("rows")) rows_count = e.attribute("rows").toInt(); - if (e.hasAttribute("rowsize")) rows_height = e.attribute("rowsize").toInt(); - if (e.hasAttribute("displaycols")) display_columns = e.attribute("displaycols") == "true"; - if (e.hasAttribute("displayrows")) display_rows = e.attribute("displayrows") == "true"; +bool BorderProperties::fromXmlPriv(const QDomElement &e) { + + if (QETXML::propertyInteger(e, "cols", &columns_count) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(e, "colsize", &columns_width) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyInteger(e, "rows", &rows_count) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(e, "rowsize", &rows_height) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyBool(e, "displaycols", &display_columns) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyBool(e, "displayrows", &display_rows) == QETXML::PropertyFlags::NoValidConversion) + return false; + + return true; +} + +bool BorderProperties::valideXml(QDomElement& e) { + + if (QETXML::propertyInteger(e, "cols") == QETXML::PropertyFlags::Success || + QETXML::propertyDouble(e, "colsize") == QETXML::PropertyFlags::Success || + QETXML::propertyInteger(e, "rows") == QETXML::PropertyFlags::Success || + QETXML::propertyDouble(e, "rowsize") == QETXML::PropertyFlags::Success || + QETXML::propertyBool(e, "displaycols") == QETXML::PropertyFlags::Success || + QETXML::propertyBool(e, "displayrows") == QETXML::PropertyFlags::Success) + return true; + return false; } /** @@ -138,11 +146,11 @@ void BorderProperties::fromXml(QDomElement &e) { */ void BorderProperties::toSettings(QSettings &settings, const QString &prefix) const { - settings.setValue(prefix + "cols", columns_count); - settings.setValue(prefix + "colsize", columns_width); + settings.setValue(prefix + "cols", columns_count); + settings.setValue(prefix + "colsize", columns_width); settings.setValue(prefix + "displaycols", display_columns); - settings.setValue(prefix + "rows", rows_count); - settings.setValue(prefix + "rowsize", rows_height); + settings.setValue(prefix + "rows", rows_count); + settings.setValue(prefix + "rowsize", rows_height); settings.setValue(prefix + "displayrows", display_rows); } @@ -156,13 +164,13 @@ void BorderProperties::toSettings(QSettings &settings, const QString &prefix) co \~French prefixe a ajouter devant les noms des parametres */ void BorderProperties::fromSettings(QSettings &settings, const QString &prefix) { - columns_count = settings.value(prefix + "cols", columns_count).toInt(); + columns_count = settings.value(prefix + "cols", columns_count).toInt(); columns_width = qRound(settings.value(prefix + "colsize", columns_width).toDouble()); - display_columns = settings.value(prefix + "displaycols", display_columns).toBool(); + display_columns = settings.value(prefix + "displaycols", display_columns).toBool(); - rows_count = settings.value(prefix + "rows", rows_count).toInt(); - rows_height = qRound(settings.value(prefix + "rowsize", rows_height).toDouble()); - display_rows = settings.value(prefix + "displayrows", display_rows).toBool(); + rows_count = settings.value(prefix + "rows", rows_count).toInt(); + rows_height = qRound(settings.value(prefix + "rowsize", rows_height).toDouble()); + display_rows = settings.value(prefix + "displayrows", display_rows).toBool(); } /** diff --git a/sources/borderproperties.h b/sources/borderproperties.h index 2120b743c..0c5a305bc 100644 --- a/sources/borderproperties.h +++ b/sources/borderproperties.h @@ -20,13 +20,15 @@ #include #include +#include "properties/propertiesinterface.h" + /** @brief The BorderProperties class This class is a container for dimensions and display properties of a diagram. @remark Attributes are public */ -class BorderProperties { +class BorderProperties : public PropertiesInterface { public: // constructor, destructor, operators BorderProperties(); @@ -35,22 +37,23 @@ class BorderProperties { bool operator==(const BorderProperties &); bool operator!=(const BorderProperties &); - void toXml(QDomElement &) const; - void fromXml(QDomElement &); - void toSettings(QSettings &, const QString & = QString()) const; - void fromSettings(QSettings &, const QString & = QString()); + void toXmlPriv(QDomElement&) const override; + bool fromXmlPriv(const QDomElement &) override; + static bool valideXml(QDomElement& e); + void toSettings(QSettings &, const QString & = QString()) const override; + void fromSettings(QSettings &, const QString & = QString()) override; static BorderProperties defaultProperties(); // attributes - int columns_count; ///< Columns count - qreal columns_width; ///< Columns width - qreal columns_header_height; ///< Column headers height - bool display_columns; ///< Whether to display column headers + int columns_count{17}; ///< Columns count + qreal columns_width{60.0}; ///< Columns width + qreal columns_header_height{20.0}; ///< Column headers height + bool display_columns{true}; ///< Whether to display column headers - int rows_count; ///< Rows count - qreal rows_height; ///< Rows height - qreal rows_header_width; ///< Row headers width - bool display_rows; ///< Whether to display row headers + int rows_count{8}; ///< Rows count + qreal rows_height{80.0}; ///< Rows height + qreal rows_header_width{20.0}; ///< Row headers width + bool display_rows{true}; ///< Whether to display row headers }; #endif diff --git a/sources/bordertitleblock.cpp b/sources/bordertitleblock.cpp index aa40c71aa..f041af066 100644 --- a/sources/bordertitleblock.cpp +++ b/sources/bordertitleblock.cpp @@ -65,8 +65,6 @@ BorderTitleBlock::BorderTitleBlock(QObject *parent) : // contenu par defaut du cartouche importTitleBlock(TitleBlockProperties()); - display_titleblock_ = true; - display_border_ = true; setFolioData(1, 1); updateRectangles(); } @@ -87,14 +85,14 @@ QRectF BorderTitleBlock::titleBlockRect() const { if (m_edge == Qt::BottomEdge) return QRectF(diagram_rect_.bottomLeft(), - QSize(diagram_rect_.width(), - m_titleblock_template_renderer -> height() - )); + QSize(diagram_rect_.width(), + m_titleblock_template_renderer -> height() + )); else return QRectF(diagram_rect_.topRight(), - QSize(m_titleblock_template_renderer -> height(), - diagram_rect_.height() - )); + QSize(m_titleblock_template_renderer -> height(), + diagram_rect_.height() + )); } /** @@ -125,9 +123,9 @@ QRectF BorderTitleBlock::titleBlockRectForQPainter() const return titleBlockRect(); else return QRectF (diagram_rect_.bottomRight(), - QSize(diagram_rect_.height(), - m_titleblock_template_renderer -> height() - )); + QSize(diagram_rect_.height(), + m_titleblock_template_renderer -> height() + )); } @@ -151,9 +149,9 @@ QRectF BorderTitleBlock::columnsRect() const { if (!display_columns_) return QRectF(); return QRectF (Diagram::margin, - Diagram::margin, - (columns_count_*columns_width_) + rows_header_width_, - columns_header_height_); + Diagram::margin, + (columns_count_*columns_width_) + rows_header_width_, + columns_header_height_); } /** @@ -165,9 +163,9 @@ QRectF BorderTitleBlock::rowsRect() const { if (!display_rows_) return QRectF(); return QRectF (Diagram::margin, - Diagram::margin, - rows_header_width_, - (rows_count_*rows_height_) + columns_header_height_); + Diagram::margin, + rows_header_width_, + (rows_count_*rows_height_) + columns_header_height_); } /** @@ -178,9 +176,9 @@ QRectF BorderTitleBlock::rowsRect() const QRectF BorderTitleBlock::outsideBorderRect() const { return QRectF (Diagram::margin, - Diagram::margin, - (columns_width_*columns_count_) + rows_header_width_, - (rows_height_*rows_count_) + columns_header_height_); + Diagram::margin, + (columns_width_*columns_count_) + rows_header_width_, + (rows_height_*rows_count_) + columns_header_height_); } /** @@ -207,8 +205,8 @@ QRectF BorderTitleBlock::insideBorderRect() const Exports the title block current values to XML. @param xml_elmt the XML element attributes will be added to */ -void BorderTitleBlock::titleBlockToXml(QDomElement &xml_elmt) { - exportTitleBlock().toXml(xml_elmt); +QDomElement BorderTitleBlock::titleBlockToXml(QDomDocument& doc) { + return exportTitleBlock().toXml(doc); } /** @@ -217,9 +215,23 @@ void BorderTitleBlock::titleBlockToXml(QDomElement &xml_elmt) { @param xml_elmt the XML element values will be read from */ void BorderTitleBlock::titleBlockFromXml(const QDomElement &xml_elmt) { - TitleBlockProperties tbp; - tbp.fromXml(xml_elmt); - importTitleBlock(tbp); + + TitleBlockProperties tbp; + QString tagname = tbp.tagName(); + QDomElement titleBlockProperties = xml_elmt.firstChildElement(tagname); + + if (!titleBlockProperties.isNull()) + { + tbp.fromXml(titleBlockProperties); + importTitleBlock(tbp); + } + else + { + // legacy + // Remove this part in a later step + tbp.fromXml(xml_elmt); + importTitleBlock(tbp); + } } /** @@ -228,12 +240,12 @@ void BorderTitleBlock::titleBlockFromXml(const QDomElement &xml_elmt) { @param xml_elmt the XML element attributes will be added to */ void BorderTitleBlock::borderToXml(QDomElement &xml_elmt) { - xml_elmt.setAttribute("cols", columnsCount()); - xml_elmt.setAttribute("colsize", QString("%1").arg(columnsWidth())); + xml_elmt.setAttribute("cols", columnsCount()); + xml_elmt.setAttribute("colsize", QString("%1").arg(columnsWidth())); xml_elmt.setAttribute("displaycols", columnsAreDisplayed() ? "true" : "false"); - xml_elmt.setAttribute("rows", rowsCount()); - xml_elmt.setAttribute("rowsize", QString("%1").arg(rowsHeight())); + xml_elmt.setAttribute("rows", rowsCount()); + xml_elmt.setAttribute("rowsize", QString("%1").arg(rowsHeight())); xml_elmt.setAttribute("displayrows", rowsAreDisplayed() ? "true" : "false"); // attribut datant de la version 0.1 - laisse pour retrocompatibilite @@ -500,9 +512,9 @@ void BorderTitleBlock::updateRectangles() { QRectF previous_diagram = diagram_rect_; diagram_rect_ = QRectF(Diagram::margin, - Diagram::margin, - diagramWidth(), - diagramHeight()); + Diagram::margin, + diagramWidth(), + diagramHeight()); if (diagram_rect_ != previous_diagram) emit(borderChanged(previous_diagram, diagram_rect_)); } @@ -554,14 +566,14 @@ void BorderTitleBlock::draw(QPainter *painter) painter -> drawRect(numbered_rectangle); if (settings.value("border-columns_0", true).toBool()){ painter -> drawText(numbered_rectangle, - Qt::AlignVCenter - | Qt::AlignCenter, - QString("%1").arg(i - 1)); + Qt::AlignVCenter + | Qt::AlignCenter, + QString("%1").arg(i - 1)); }else{ painter -> drawText(numbered_rectangle, - Qt::AlignVCenter - | Qt::AlignCenter, - QString("%1").arg(i)); + Qt::AlignVCenter + | Qt::AlignCenter, + QString("%1").arg(i)); } } } @@ -582,9 +594,9 @@ void BorderTitleBlock::draw(QPainter *painter) ); painter -> drawRect(lettered_rectangle); painter -> drawText(lettered_rectangle, - Qt::AlignVCenter - | Qt::AlignCenter, - row_string); + Qt::AlignVCenter + | Qt::AlignCenter, + row_string); row_string = incrementLetters(row_string); } } @@ -626,9 +638,9 @@ void BorderTitleBlock::drawDxf( { // Transform to DXF scale. columns_header_height_ *= Createdxf::yScale; - rows_height_ *= Createdxf::yScale; - rows_header_width_ *= Createdxf::xScale; - columns_width_ *= Createdxf::xScale; + rows_height_ *= Createdxf::yScale; + rows_header_width_ *= Createdxf::xScale; + columns_width_ *= Createdxf::xScale; // draw the empty box that appears as soon as there is a header // dessine la case vide qui apparait des qu'il y a un entete @@ -657,11 +669,11 @@ void BorderTitleBlock::drawDxf( display_columns_) { int offset = settings.value("border-columns_0", true).toBool() ? -1 : 0; for (int i = 1 ; i <= columns_count_ ; ++ i) { - double xCoord = diagram_rect_.topLeft().x() * Createdxf::xScale + + double xCoord = diagram_rect_.topLeft().x() * Createdxf::xScale + (rows_header_width_ + ((i - 1) * columns_width_)); double yCoord = Createdxf::sheetHeight - - diagram_rect_.topLeft().y()*Createdxf::yScale + - diagram_rect_.topLeft().y()*Createdxf::yScale - columns_header_height_; double recWidth = columns_width_; double recHeight = columns_header_height_; @@ -690,8 +702,8 @@ void BorderTitleBlock::drawDxf( for (int i = 1 ; i <= rows_count_ ; ++ i) { double xCoord = diagram_rect_.topLeft().x() * Createdxf::xScale; - double yCoord = Createdxf::sheetHeight - - diagram_rect_.topLeft().y() + double yCoord = Createdxf::sheetHeight + - diagram_rect_.topLeft().y() *Createdxf::yScale - ( columns_header_height_ @@ -723,17 +735,17 @@ void BorderTitleBlock::drawDxf( //qp -> translate(titleblock_rect_.topLeft()); QRectF rect = titleBlockRect(); m_titleblock_template_renderer -> renderDxf(rect, - rect.width(), - file_path, - color); + rect.width(), + file_path, + color); //qp -> translate(-titleblock_rect_.topLeft()); } // Transform back to QET scale columns_header_height_ /= Createdxf::yScale; rows_height_ /= Createdxf::yScale; - rows_header_width_ /= Createdxf::xScale; - columns_width_ /= Createdxf::xScale; + rows_header_width_ /= Createdxf::xScale; + columns_width_ /= Createdxf::xScale; } @@ -853,7 +865,7 @@ void BorderTitleBlock::setRowsHeaderWidth(const qreal &new_rhw) { \~ @param height : */ void BorderTitleBlock::setDiagramHeight(const qreal &height) { - // size of rows to use = rows_height + // size of rows to use = rows_height // taille des lignes a utiliser = rows_height setRowsCount(qRound(ceil(height / rows_height_))); } @@ -871,7 +883,7 @@ DiagramPosition BorderTitleBlock::convertPosition(const QPointF &pos) return (DiagramPosition("", 0)); QPointF relative_pos = pos - insideBorderRect().topLeft(); - int row_number = int(ceil(relative_pos.x() / columnsWidth())); + int row_number = int(ceil(relative_pos.x() / columnsWidth())); int column_number = int(ceil(relative_pos.y() / rowsHeight())); QString letter = "A"; @@ -939,18 +951,18 @@ void BorderTitleBlock::updateDiagramContextForTitleBlock( // ... overridden by the historical and/or dynamically generated fields QLocale var; var.dateFormat(QLocale::ShortFormat); - context.addValue("author", btb_author_); + context.addValue("author", btb_author_); context.addValue( "date", QLocale::system().toString(btb_date_, QLocale::ShortFormat)); - context.addValue("title", btb_title_); - context.addValue("filename", btb_filename_); - context.addValue("plant", btb_plant_); - context.addValue("locmach", btb_locmach_); - context.addValue("indexrev", btb_indexrev_); - context.addValue("version", btb_version_); - context.addValue("folio", btb_final_folio_); - context.addValue("folio-id", folio_index_); + context.addValue("title", btb_title_); + context.addValue("filename", btb_filename_); + context.addValue("plant", btb_plant_); + context.addValue("locmach", btb_locmach_); + context.addValue("indexrev", btb_indexrev_); + context.addValue("version", btb_version_); + context.addValue("folio", btb_final_folio_); + context.addValue("folio-id", folio_index_); context.addValue("folio-total", folio_total_); context.addValue("auto_page_num", btb_auto_page_num_); context.addValue("previous-folio-num", m_previous_folio_num); @@ -1028,7 +1040,7 @@ void BorderTitleBlock::setFolioData( btb_final_folio_.replace("%autonum", autonum); btb_folio_ = btb_final_folio_; } - btb_final_folio_.replace("%id", QString::number(folio_index_)); + btb_final_folio_.replace("%id", QString::number(folio_index_)); btb_final_folio_.replace("%total", QString::number(folio_total_)); updateDiagramContextForTitleBlock(project_properties); diff --git a/sources/bordertitleblock.h b/sources/bordertitleblock.h index 148e3917b..56fb12069 100644 --- a/sources/bordertitleblock.h +++ b/sources/bordertitleblock.h @@ -174,7 +174,7 @@ class BorderTitleBlock : public QObject void setPreviousFolioNum(const QString &previous); void setNextFolioNum(const QString &next); - void titleBlockToXml(QDomElement &); + QDomElement titleBlockToXml(QDomDocument &doc); void titleBlockFromXml(const QDomElement &); void borderToXml(QDomElement &); void borderFromXml(const QDomElement &); @@ -249,34 +249,34 @@ class BorderTitleBlock : public QObject // attributes private: // titleblock basic data - QString btb_author_; ///< titleblock author - QDate btb_date_; ///< titleblock date - QString btb_title_; ///< titleblock title - QString btb_folio_; ///< titleblock folio - QString btb_plant_; ///< titleblock plant - QString btb_locmach_; ///< titleblock locmach - QString btb_indexrev_; ///< titleblock index rev + QString btb_author_; ///< titleblock author + QDate btb_date_; ///< titleblock date + QString btb_title_; ///< titleblock title + QString btb_folio_; ///< titleblock folio + QString btb_plant_; ///< titleblock plant + QString btb_locmach_; ///< titleblock locmach + QString btb_indexrev_; ///< titleblock index rev QString btb_final_folio_; ///< titleblock final folio QString btb_auto_page_num_; ///< titleblock auto page num - int folio_index_; ///< titleblock index - int folio_total_; ///< titleblock total - QString btb_filename_; ///< titleblock filename - QString btb_version_; ///< titleblock version + int folio_index_; ///< titleblock index + int folio_total_; ///< titleblock total + QString btb_filename_; ///< titleblock filename + QString btb_version_; ///< titleblock version /// titleblock additional fields DiagramContext additional_fields_; - Qt::Edge m_edge; ///< titleblock edge - QString m_next_folio_num; ///< titleblock next folio num + Qt::Edge m_edge; ///< titleblock edge + QString m_next_folio_num; ///< titleblock next folio num QString m_previous_folio_num; ///< titleblock previous folio num // border dimensions (rows and columns) // columns: number and dimensions - int columns_count_; ///< columns count - qreal columns_width_; ///< columns width + int columns_count_; ///< columns count + qreal columns_width_; ///< columns width qreal columns_header_height_; ///< columns header height // rows: number and dimensions - int rows_count_; ///< rows count - qreal rows_height_; ///< rows height + int rows_count_; ///< rows count + qreal rows_height_; ///< rows height qreal rows_header_width_; ///< rows header width // title block dimensions @@ -286,10 +286,10 @@ class BorderTitleBlock : public QObject QRectF diagram_rect_; // display options - bool display_titleblock_; + bool display_titleblock_{true}; bool display_columns_; bool display_rows_; - bool display_border_; + bool display_border_{true}; TitleBlockTemplateRenderer *m_titleblock_template_renderer; }; #endif diff --git a/sources/conductorproperties.cpp b/sources/conductorproperties.cpp index 233762c48..8844f6414 100644 --- a/sources/conductorproperties.cpp +++ b/sources/conductorproperties.cpp @@ -20,14 +20,16 @@ #include #include #include + +#include "qetxml.h" + +namespace { + const QString conductorPropertiesXmlName = "conductorProperties"; +} /** Constructeur par defaut */ -SingleLineProperties::SingleLineProperties() : - hasGround(true), - hasNeutral(true), - is_pen(false), - phases(1) +SingleLineProperties::SingleLineProperties(): PropertiesInterface("SingleLine") { } @@ -123,9 +125,9 @@ void SingleLineProperties::draw(QPainter *painter, @param size taille du segment */ void SingleLineProperties::drawGround(QPainter *painter, - QET::ConductorSegmentType direction, - QPointF center, - qreal size) { + QET::ConductorSegmentType direction, + QPointF center, + qreal size) { painter -> save(); // prepare le QPainter @@ -215,12 +217,12 @@ void SingleLineProperties::drawPen(QPainter *painter, ajoutes a l'element e. @param e Element XML auquel seront ajoutes des attributs */ -void SingleLineProperties::toXml(QDomElement &e) const -{ - e.setAttribute("ground", hasGround ? "true" : "false"); - e.setAttribute("neutral", hasNeutral ? "true" : "false"); - e.setAttribute("phase", phases); - if (isPen()) e.setAttribute("pen", "true"); +void SingleLineProperties::toXmlPriv(QDomElement& e) const { + + e.setAttribute("ground", hasGround ? "true" : "false"); + e.setAttribute("neutral", hasNeutral ? "true" : "false"); + e.setAttribute("phase", phases); + if (isPen()) e.setAttribute("pen", "true"); } /** @@ -228,11 +230,36 @@ void SingleLineProperties::toXml(QDomElement &e) const de l'element e @param e Element XML dont les attributs seront lus */ -void SingleLineProperties::fromXml(QDomElement &e) { - hasGround = e.attribute("ground") == "true"; - hasNeutral = e.attribute("neutral") == "true"; - setPhasesCount(e.attribute("phase").toInt()); - is_pen = (hasGround && hasNeutral && e.attribute("pen", "false") == "true"); +bool SingleLineProperties::fromXmlPriv(const QDomElement &e) { + if (QETXML::propertyBool(e, "ground", &hasGround) != QETXML::PropertyFlags::Success || + QETXML::propertyBool(e, "neutral", &hasNeutral) != QETXML::PropertyFlags::Success) + return false; + + int phase; + if (QETXML::propertyInteger(e, "phase", &phase) != QETXML::PropertyFlags::Success) + return false; + setPhasesCount(phase); + + bool pen; + if (QETXML::propertyBool(e, "pen", &pen) != QETXML::PropertyFlags::Success) + return false; + is_pen = (hasGround && hasNeutral && pen); + + return true; +} + +bool SingleLineProperties::valideXml(QDomElement& e) { + if (QETXML::propertyBool(e, "ground") != QETXML::PropertyFlags::Success || + QETXML::propertyBool(e, "neutral") != QETXML::PropertyFlags::Success) + return false; + + if (QETXML::propertyInteger(e, "phase") != QETXML::PropertyFlags::Success) + return false; + + if (QETXML::propertyBool(e, "pen") != QETXML::PropertyFlags::Success) + return false; + + return true; } /** @@ -240,17 +267,7 @@ void SingleLineProperties::fromXml(QDomElement &e) { multifilaire noir dont le texte est "_" */ ConductorProperties::ConductorProperties() : - type(Multi), - color(Qt::black), - text_color(Qt::black), - text("_"), - text_size(9), - cond_size(1), - verti_rotate_text(270), - horiz_rotate_text(0), - m_show_text(true), - m_one_text_per_folio(false), - style(Qt::SolidLine) + PropertiesInterface(xmlTagName()) {} /** @@ -266,108 +283,143 @@ ConductorProperties::~ConductorProperties() Export conductor propertie, in the XML element 'e' @param e the xml element */ -void ConductorProperties::toXml(QDomElement &e) const +void ConductorProperties::toXmlPriv(QDomElement& e) const { - e.setAttribute("type", typeToString(type)); - if (color != QColor(Qt::black)) - e.setAttribute("color", color.name()); + e.setAttribute("type", typeToString(type)); - e.setAttribute("bicolor", m_bicolor? "true" : "false"); - e.setAttribute("color2", m_color_2.name()); - e.setAttribute("dash-size", QString::number(m_dash_size)); + if (color != QColor(Qt::black)) + e.setAttribute("color", color.name()); - if (type == Single) - singleLineProperties.toXml(e); + e.setAttribute("bicolor", m_bicolor? "true" : "false"); + e.setAttribute("color2", m_color_2.name()); + e.setAttribute("dash-size", QString::number(m_dash_size)); - e.setAttribute("num", text); - e.setAttribute("text_color", text_color.name()); - e.setAttribute("formula", m_formula); - e.setAttribute("cable", m_cable); - e.setAttribute("bus", m_bus); - e.setAttribute("function", m_function); - e.setAttribute("tension_protocol", m_tension_protocol); - e.setAttribute("conductor_color", m_wire_color); - e.setAttribute("conductor_section", m_wire_section); - e.setAttribute("numsize", QString::number(text_size)); - e.setAttribute("condsize", QString::number(cond_size)); - e.setAttribute("displaytext", m_show_text); - e.setAttribute("onetextperfolio", m_one_text_per_folio); - e.setAttribute("vertirotatetext", QString::number(verti_rotate_text)); - e.setAttribute("horizrotatetext", QString::number(horiz_rotate_text)); + if (type == Single) + { + QDomDocument doc = e.ownerDocument(); + singleLineProperties.toXml(doc); + } - QMetaEnum me = QMetaEnum::fromType(); - e.setAttribute("horizontal-alignment", me.valueToKey(m_horizontal_alignment)); - e.setAttribute("vertical-alignment", me.valueToKey(m_vertical_alignment)); + e.setAttribute("num", text); + e.setAttribute("text_color", text_color.name()); + e.setAttribute("formula", m_formula); + e.setAttribute("cable", m_cable); + e.setAttribute("bus", m_bus); + e.setAttribute("function", m_function); + e.setAttribute("tension_protocol", m_tension_protocol); + e.setAttribute("conductor_color", m_wire_color); + e.setAttribute("conductor_section", m_wire_section); + e.setAttribute("numsize", QString::number(text_size)); + e.setAttribute("condsize", QString::number(cond_size)); + e.setAttribute("displaytext", m_show_text); + e.setAttribute("onetextperfolio", m_one_text_per_folio); + e.setAttribute("vertirotatetext", QString::number(verti_rotate_text)); + e.setAttribute("horizrotatetext", QString::number(horiz_rotate_text)); - QString conductor_style = writeStyle(); - if (!conductor_style.isEmpty()) - e.setAttribute("style", conductor_style); + QMetaEnum me = QMetaEnum::fromType(); + e.setAttribute("horizontal-alignment", me.valueToKey(m_horizontal_alignment)); + e.setAttribute("vertical-alignment", me.valueToKey(m_vertical_alignment)); + + QString conductor_style = writeStyle(); + if (!conductor_style.isEmpty()) + e.setAttribute("style", conductor_style); } -/** +/** RETURNS True @brief ConductorProperties::fromXml Import conductor propertie, from the attribute of the xml element 'e' @param e the xml document */ -void ConductorProperties::fromXml(QDomElement &e) +bool ConductorProperties::fromXmlPriv(const QDomElement &e) { // get conductor color - QColor xml_color= QColor(e.attribute("color")); - color = (xml_color.isValid()? xml_color : QColor(Qt::black)); - - QString bicolor_str = e.attribute("bicolor", "false"); - m_bicolor = bicolor_str == "true"? true : false; - - QColor xml_color_2 = QColor(e.attribute("color2")); - m_color_2 = xml_color_2.isValid()? xml_color_2 : QColor(Qt::black); - - m_dash_size = e.attribute("dash-size", QString::number(1)).toInt(); + QETXML::propertyColor(e, "color", &color); + QETXML::propertyBool(e, "bicolor", &m_bicolor); + QETXML::propertyColor(e, "color2", &m_color_2); + QETXML::propertyInteger(e, "dash-size", &m_dash_size); // read style of conductor - readStyle(e.attribute("style")); + QString style_string; + QETXML::propertyString(e, "style", &style_string); + readStyle(style_string); - if (e.attribute("type") == typeToString(Single)) + QString type_t; + if (QETXML::propertyString(e, "type", &type_t) == QETXML::PropertyFlags::Success) { + if (type_t == typeToString(Single)) { // get specific properties for single conductor singleLineProperties.fromXml(e); type = Single; } - else + else if (type_t == typeToString(Multi)) type = Multi; + else { + //Keep retrocompatible with version older than 0,4 + //If the propertie @type is simple (removed since QET 0,4), we set text no visible. + //@TODO remove this code for qet 0.6 or later - text = e.attribute("num"); + if (type_t == "simple") m_show_text = false; + } + } + + QETXML::propertyString(e, "num", &text); + // TODO: implement: + //m_cable = e.attribute("cable"); + //m_bus = e.attribute("bus"); // get text color - QColor xml_text_color= QColor(e.attribute("text_color")); - text_color = (xml_text_color.isValid()? xml_text_color : QColor(Qt::black)); - m_formula = e.attribute("formula"); - m_cable = e.attribute("cable"); - m_bus = e.attribute("bus"); - m_function = e.attribute("function"); - m_tension_protocol = e.attribute("tension_protocol"); - m_wire_color = e.attribute("conductor_color"); - m_wire_section = e.attribute("conductor_section"); - text_size = e.attribute("numsize", QString::number(9)).toInt(); - cond_size = e.attribute("condsize", QString::number(1)).toDouble(); - m_show_text = e.attribute("displaytext", QString::number(1)).toInt(); - m_one_text_per_folio = e.attribute("onetextperfolio", QString::number(0)).toInt(); - verti_rotate_text = e.attribute("vertirotatetext").toDouble(); - horiz_rotate_text = e.attribute("horizrotatetext").toDouble(); + QETXML::propertyColor(e, "text_color", &text_color); + QETXML::propertyString(e, "formula", &m_formula); + QETXML::propertyString(e, "function", &m_function); + QETXML::propertyString(e, "tension_protocol", &m_tension_protocol); + QETXML::propertyString(e, "conductor_color", &m_wire_color); + QETXML::propertyString(e, "conductor_section", &m_wire_section); + QETXML::propertyInteger(e, "numsize", &text_size); + QETXML::propertyDouble(e, "condsize", &cond_size); + QETXML::propertyBool(e, "displaytext", &m_show_text); + QETXML::propertyBool(e, "onetextperfolio", &m_one_text_per_folio); + QETXML::propertyDouble(e, "vertirotatetext", &verti_rotate_text); + QETXML::propertyDouble(e, "horizrotatetext", &horiz_rotate_text); QMetaEnum me = QMetaEnum::fromType(); - m_horizontal_alignment = Qt::Alignment( - me.keyToValue( - e.attribute( - "horizontal-alignment", - "AlignBottom" - ).toStdString().data())); - m_vertical_alignment = Qt::Alignment( - me.keyToValue( - e.attribute( - "vertical-alignment", - "AlignRight" - ).toStdString().data())); + QString alinment_temp; + if (QETXML::propertyString(e, "horizontal-alignment", &alinment_temp) == QETXML::PropertyFlags::Success) + m_horizontal_alignment = Qt::Alignment(me.keyToValue(alinment_temp.toStdString().data())); + if (QETXML::propertyString(e, "vertical-alignment", &alinment_temp) == QETXML::PropertyFlags::Success) + m_vertical_alignment = Qt::Alignment(me.keyToValue(alinment_temp.toStdString().data())); + + return true; +} + +bool ConductorProperties::valideXml(QDomElement& e) { + if (QETXML::propertyColor(e, "color") || + QETXML::propertyBool(e, "bicolor") || + QETXML::propertyColor(e, "color2") || + QETXML::propertyInteger(e, "dash-size") || + QETXML::propertyString(e, "type") || + QETXML::propertyString(e, "num") || + QETXML::propertyColor(e, "text_color") || + QETXML::propertyString(e, "formula") || + QETXML::propertyString(e, "function") || + QETXML::propertyString(e, "tension_protocol") || + QETXML::propertyString(e, "conductor_color") || + QETXML::propertyString(e, "conductor_section") || + QETXML::propertyInteger(e, "numsize") || + QETXML::propertyDouble(e, "condsize") || + QETXML::propertyBool(e, "displaytext") || + QETXML::propertyBool(e, "onetextperfolio") || + QETXML::propertyDouble(e, "vertirotatetext") || + QETXML::propertyDouble(e, "horizrotatetext") || + QETXML::propertyString(e, "horizontal-alignment") || + QETXML::propertyString(e, "vertical-alignment")) + return false; + return true; +} + +QString ConductorProperties::xmlTagName() +{ + return conductorPropertiesXmlName; } /** @@ -425,22 +477,22 @@ void ConductorProperties::fromSettings(QSettings &settings, const QString &prefi singleLineProperties.fromSettings(settings, prefix); - text = settings.value(prefix + "text", "_").toString(); + text = settings.value(prefix + "text", "_").toString(); QColor settings_text_color = QColor(settings.value(prefix + "text_color").toString()); text_color = (settings_text_color.isValid()? settings_text_color : QColor(Qt::black)); - m_formula = settings.value(prefix + "formula", "").toString(); - m_cable = settings.value(prefix + "cable", "").toString(); - m_bus = settings.value(prefix + "bus", "").toString(); - m_function = settings.value(prefix + "function", "").toString(); + m_formula = settings.value(prefix + "formula", "").toString(); + m_cable = settings.value(prefix + "cable", "").toString(); + m_bus = settings.value(prefix + "bus", "").toString(); + m_function = settings.value(prefix + "function", "").toString(); m_tension_protocol = settings.value(prefix + "tension_protocol", "").toString(); - m_wire_color = settings.value(prefix + "conductor_color", "").toString(); - m_wire_section = settings.value(prefix + "conductor_section", "").toString(); - text_size = settings.value(prefix + "textsize", "7").toInt(); - cond_size = settings.value(prefix + "size", "1").toInt(); - m_show_text = settings.value(prefix + "displaytext", true).toBool(); + m_wire_color = settings.value(prefix + "conductor_color", "").toString(); + m_wire_section = settings.value(prefix + "conductor_section", "").toString(); + text_size = settings.value(prefix + "textsize", "7").toInt(); + cond_size = settings.value(prefix + "size", "1").toInt(); + m_show_text = settings.value(prefix + "displaytext", true).toBool(); m_one_text_per_folio = settings.value(prefix + "onetextperfolio", false).toBool(); - verti_rotate_text = settings.value((prefix + "vertirotatetext"), "270").toDouble(); - horiz_rotate_text = settings.value((prefix + "horizrotatetext"), "0").toDouble(); + verti_rotate_text = settings.value((prefix + "vertirotatetext"), "270").toDouble(); + horiz_rotate_text = settings.value((prefix + "horizrotatetext"), "0").toDouble(); QMetaEnum me = QMetaEnum::fromType(); m_horizontal_alignment = Qt::Alignment(me.keyToValue(settings.value(prefix + "horizontal-alignment", "AlignBottom").toString().toStdString().data())); @@ -478,25 +530,25 @@ void ConductorProperties::applyForEqualAttributes(QList lis if (clist.size() == 1) { ConductorProperties cp = clist.first(); - color = cp.color; - m_bicolor = cp.m_bicolor; - m_color_2 = cp.m_color_2; - m_dash_size = cp.m_dash_size; - text = cp.text; - text_color = cp.text_color; - m_formula = cp.m_formula; - m_cable = cp.m_cable; - m_bus = cp.m_bus; - m_function = cp.m_function; + color = cp.color; + m_bicolor = cp.m_bicolor; + m_color_2 = cp.m_color_2; + m_dash_size = cp.m_dash_size; + text = cp.text; + text_color = cp.text_color; + m_formula = cp.m_formula; + m_cable = cp.m_cable; + m_bus = cp.m_bus; + m_function = cp.m_function; m_tension_protocol = cp.m_tension_protocol; - m_wire_color = cp.m_wire_color; - m_wire_section = cp.m_wire_section; - text_size = cp.text_size; - cond_size = cp.cond_size; - m_show_text = cp.m_show_text; + m_wire_color = cp.m_wire_color; + m_wire_section = cp.m_wire_section; + text_size = cp.text_size; + cond_size = cp.cond_size; + m_show_text = cp.m_show_text; m_one_text_per_folio = cp.m_one_text_per_folio; - verti_rotate_text = cp.verti_rotate_text; - horiz_rotate_text = cp.horiz_rotate_text; + verti_rotate_text = cp.verti_rotate_text; + horiz_rotate_text = cp.horiz_rotate_text; m_vertical_alignment = cp.m_vertical_alignment; m_horizontal_alignment = cp.m_horizontal_alignment; @@ -834,7 +886,7 @@ void ConductorProperties::readStyle(const QString &style_string) { if (!match.hasMatch()) { qDebug()<<"no Match" - < #include +#include "properties/propertiesinterface.h" + class QPainter; /** @brief The SingleLineProperties class This class represents the properties of a singleline conductor. */ -class SingleLineProperties { +class SingleLineProperties: public PropertiesInterface { public: SingleLineProperties(); virtual ~SingleLineProperties(); @@ -37,23 +39,24 @@ class SingleLineProperties { unsigned short int phasesCount(); bool isPen() const; void draw(QPainter *, QET::ConductorSegmentType, const QRectF &); - void toXml(QDomElement &) const; - void fromXml(QDomElement &); + void toXmlPriv(QDomElement&) const override; + bool fromXmlPriv(const QDomElement &) override; + static bool valideXml(QDomElement& element); void toSettings(QSettings &, const QString & = QString()) const; void fromSettings(QSettings &, const QString & = QString()); /// Whether the singleline conductor should display the ground symbol - bool hasGround; + bool hasGround{true}; /// Whether the singleline conductor should display the neutral symbol - bool hasNeutral; + bool hasNeutral{true}; /// Protective Earth Neutral: visually merge neutral and ground - bool is_pen; + bool is_pen{false}; int operator==(const SingleLineProperties &) const; int operator!=(const SingleLineProperties &) const; private: - unsigned short int phases; + unsigned short int phases{1}; void drawGround (QPainter *, QET::ConductorSegmentType, QPointF, qreal); void drawNeutral(QPainter *, QPointF, qreal); void drawPen(QPainter *, QET::ConductorSegmentType, QPointF, qreal); @@ -64,7 +67,7 @@ class SingleLineProperties { This class represents the functional properties of a particular conductor, i.e. properties other than path and terminals. */ -class ConductorProperties +class ConductorProperties: public PropertiesInterface { public: ConductorProperties(); @@ -80,15 +83,15 @@ class ConductorProperties //Attributes - ConductorType type; + ConductorType type{ConductorType::Multi}; - QColor - color, - m_color_2, - text_color; + // TODO: set default values! + QColor color{QColor(Qt::black)}, + m_color_2{QColor(Qt::black)}, + text_color{QColor(Qt::black)}; QString - text, + text{"_"}, m_function, m_tension_protocol, m_wire_color, @@ -97,33 +100,31 @@ class ConductorProperties m_bus, m_cable; - int - text_size, + int text_size{9}, m_dash_size = 1; - double - cond_size, - verti_rotate_text, - horiz_rotate_text; + double + cond_size{1}, + verti_rotate_text{270}, + horiz_rotate_text{0}; - bool - m_show_text, - m_one_text_per_folio, + bool m_show_text{true}, + m_one_text_per_folio{false}, m_bicolor = false; - Qt::Alignment - m_horizontal_alignment = Qt::AlignBottom, + Qt::Alignment + m_horizontal_alignment = Qt::AlignBottom, m_vertical_alignment = Qt::AlignRight; - Qt::PenStyle style; + Qt::PenStyle style{Qt::PenStyle::SolidLine}; SingleLineProperties singleLineProperties; // methods - void toXml(QDomElement &) const; - void fromXml(QDomElement &); - void toSettings(QSettings &, const QString & = QString()) const; - void fromSettings(QSettings &, const QString & = QString()); + static bool valideXml(QDomElement& element); + static QString xmlTagName(); + void toSettings(QSettings &, const QString & = QString()) const override; + void fromSettings(QSettings &, const QString & = QString()) override; static QString typeToString(ConductorType); void applyForEqualAttributes(QList list); @@ -133,6 +134,10 @@ class ConductorProperties bool operator==(const ConductorProperties &) const; bool operator!=(const ConductorProperties &) const; + private: + void toXmlPriv(QDomElement&) const override; + bool fromXmlPriv(const QDomElement &) override; + private: void readStyle(const QString &); QString writeStyle() const; diff --git a/sources/diagram.cpp b/sources/diagram.cpp index 08270708b..2ea8bf045 100644 --- a/sources/diagram.cpp +++ b/sources/diagram.cpp @@ -44,6 +44,8 @@ #include #include +#include "qetxml.h" + int Diagram::xGrid = 10; int Diagram::yGrid = 10; int Diagram::xKeyGrid = 10; @@ -64,11 +66,11 @@ QColor Diagram::background_color = Qt::white; @param project : The project of this diagram and also parent QObject */ Diagram::Diagram(QETProject *project) : - QGraphicsScene (project), - m_project (project), - draw_grid_ (true), - use_border_ (true), - draw_terminals_ (true), + QGraphicsScene (project), + m_project (project), + draw_grid_ (true), + use_border_ (true), + draw_terminals_ (true), draw_colored_conductors_ (true), m_event_interface (nullptr), m_freeze_new_elements (false), @@ -180,7 +182,7 @@ void Diagram::drawBackground(QPainter *p, const QRectF &r) { */ QPen pen; Diagram::background_color == Qt::black? pen.setColor(Qt::white) - : pen.setColor(Qt::black); + : pen.setColor(Qt::black); pen.setCosmetic(true); p->setPen(pen); @@ -326,9 +328,9 @@ void Diagram::keyPressEvent(QKeyEvent *event) { QSettings settings; int xKeyGrid = settings.value("diagrameditor/key_Xgrid", - Diagram::xKeyGrid).toInt(); + Diagram::xKeyGrid).toInt(); int yKeyGrid = settings.value("diagrameditor/key_Ygrid", - Diagram::yKeyGrid).toInt(); + Diagram::yKeyGrid).toInt(); int xKeyGridFine = settings.value("diagrameditor/key_fine_Xgrid", Diagram::xKeyGridFine).toInt(); int yKeyGridFine = settings.value("diagrameditor/key_fine_Ygrid", @@ -583,9 +585,9 @@ void Diagram::setConductorsAutonumName(const QString &name) { @return Une QImage representant le schema */ bool Diagram::toPaintDevice(QPaintDevice &pix, - int width, - int height, - Qt::AspectRatioMode aspectRatioMode) { + int width, + int height, + Qt::AspectRatioMode aspectRatioMode) { // determine the source area = schema content + margins // determine la zone source = contenu du schema + marges QRectF source_area; @@ -632,9 +634,9 @@ bool Diagram::toPaintDevice(QPaintDevice &pix, // renders itself // effectue le rendu lui-meme render(&p, - QRect(QPoint(0, 0),image_size), - source_area, - aspectRatioMode); + QRect(QPoint(0, 0),image_size), + source_area, + aspectRatioMode); p.end(); // restore selected items @@ -737,29 +739,28 @@ QDomDocument Diagram::toXml(bool whole_content) { // schema properties // proprietes du schema if (whole_content) { - border_and_titleblock.titleBlockToXml(dom_root); + // TODO: compare with old version + dom_root.appendChild(border_and_titleblock.titleBlockToXml(document)); border_and_titleblock.borderToXml(dom_root); // Default conductor properties - QDomElement default_conductor = - document.createElement("defaultconductor"); - defaultConductorProperties.toXml(default_conductor); - dom_root.appendChild(default_conductor); + defaultConductorProperties.setTagName("defaultconductor"); + dom_root.appendChild(defaultConductorProperties.toXml(document)); // Conductor autonum if (!m_conductors_autonum_name.isEmpty()) { dom_root.setAttribute("conductorAutonum", - m_conductors_autonum_name); + m_conductors_autonum_name); } //Default New Element dom_root.setAttribute("freezeNewElement", - m_freeze_new_elements ? "true" : "false"); + m_freeze_new_elements ? "true" : "false"); //Default New Conductor dom_root.setAttribute("freezeNewConductor", - m_freeze_new_conductors_ - ? "true" : "false"); + m_freeze_new_conductors_ + ? "true" : "false"); //Element Folio Sequential Variables if (!m_elmt_unitfolio_max.isEmpty() @@ -773,10 +774,10 @@ QDomDocument Diagram::toXml(bool whole_content) { document.createElement( "elementunitfolioseq"); folioSequentialsToXml(&m_elmt_unitfolio_max, - &elmtfolioseq, - "sequf_", - "unitfolioseq", - &document); + &elmtfolioseq, + "sequf_", + "unitfolioseq", + &document); elmtfoliosequential.appendChild(elmtfolioseq); } if (!m_elmt_tenfolio_max.isEmpty()) { @@ -784,10 +785,10 @@ QDomDocument Diagram::toXml(bool whole_content) { document.createElement( "elementtenfolioseq"); folioSequentialsToXml(&m_elmt_tenfolio_max, - &elmtfolioseq, - "seqtf_", - "tenfolioseq", - &document); + &elmtfolioseq, + "seqtf_", + "tenfolioseq", + &document); elmtfoliosequential.appendChild(elmtfolioseq); } if (!m_elmt_hundredfolio_max.isEmpty()) { @@ -795,10 +796,10 @@ QDomDocument Diagram::toXml(bool whole_content) { document.createElement( "elementhundredfolioseq"); folioSequentialsToXml(&m_elmt_hundredfolio_max, - &elmtfolioseq, - "seqhf_", - "hundredfolioseq", - &document); + &elmtfolioseq, + "seqhf_", + "hundredfolioseq", + &document); elmtfoliosequential.appendChild(elmtfolioseq); } dom_root.appendChild(elmtfoliosequential); @@ -816,10 +817,10 @@ QDomDocument Diagram::toXml(bool whole_content) { document.createElement( "conductorunitfolioseq"); folioSequentialsToXml(&m_cnd_unitfolio_max, - &cndfolioseq, - "sequf_", - "unitfolioseq", - &document); + &cndfolioseq, + "sequf_", + "unitfolioseq", + &document); cndfoliosequential.appendChild(cndfolioseq); } if (!m_cnd_tenfolio_max.isEmpty()) { @@ -827,10 +828,10 @@ QDomDocument Diagram::toXml(bool whole_content) { document.createElement( "conductortenfolioseq"); folioSequentialsToXml(&m_cnd_tenfolio_max, - &cndfolioseq, - "seqtf_", - "tenfolioseq", - &document); + &cndfolioseq, + "seqtf_", + "tenfolioseq", + &document); cndfoliosequential.appendChild(cndfolioseq); } if (!m_cnd_hundredfolio_max.isEmpty()) { @@ -838,10 +839,10 @@ QDomDocument Diagram::toXml(bool whole_content) { document.createElement( "conductorhundredfolioseq"); folioSequentialsToXml(&m_cnd_hundredfolio_max, - &cndfolioseq, - "seqhf_", - "hundredfolioseq", - &document); + &cndfolioseq, + "seqhf_", + "hundredfolioseq", + &document); cndfoliosequential.appendChild(cndfolioseq); } dom_root.appendChild(cndfoliosequential); @@ -918,13 +919,11 @@ QDomDocument Diagram::toXml(bool whole_content) { // correspondence table between the addresses of the terminals and their ids // table de correspondance entre les adresses des bornes et leurs ids - QHash table_adr_id; if (!list_elements.isEmpty()) { auto dom_elements = document.createElement("elements"); for (auto elmt : list_elements) { - dom_elements.appendChild(elmt->toXml(document, - table_adr_id)); + dom_elements.appendChild(elmt->toXml(document)); } dom_root.appendChild(dom_elements); } @@ -932,8 +931,7 @@ QDomDocument Diagram::toXml(bool whole_content) { if (!list_conductors.isEmpty()) { auto dom_conductors = document.createElement("conductors"); for (auto cond : list_conductors) { - dom_conductors.appendChild(cond->toXml(document, - table_adr_id)); + dom_conductors.appendChild(cond->toXml(document)); } dom_root.appendChild(dom_conductors); } @@ -983,18 +981,18 @@ QDomDocument Diagram::toXml(bool whole_content) { @param doc */ void Diagram::folioSequentialsToXml(QHash *hash, - QDomElement *domElement, - const QString& seq_type, - const QString& type, - QDomDocument *doc) { + QStringList> *hash, + QDomElement *domElement, + const QString& seq_type, + const QString& type, + QDomDocument *doc) { QHash::iterator i; for (i = hash->begin(); i != hash->end(); i++) { QDomElement folioseq = doc->createElement(type); folioseq.setAttribute("title", i.key()); for (int j = 0; j < i.value().size(); j++) { - folioseq.setAttribute(seq_type + QString::number(j+1), - i.value().at(j)); + folioseq.setAttribute(seq_type + QString::number(j+1), + i.value().at(j)); } domElement->appendChild(folioseq); } @@ -1032,9 +1030,9 @@ void Diagram::folioSequentialsToXml(QHash& table_adr_id, - QList& added_elements) { + QDomElement& conductor, + QHash& table_adr_id, + QList& added_elements) { assert(conductor_index == 1 || conductor_index == 2); QString element_index = "element" + QString::number(conductor_index); QString terminal_index = "terminal" + QString::number(conductor_index); - if (f.hasAttribute(element_index)) { - QUuid element_uuid = QUuid(f.attribute(element_index)); + QUuid element_uuid; + if (QETXML::propertyUuid(conductor, element_index, &element_uuid) == QETXML::PropertyFlags::Success) { // element1 did not exist in the conductor part of the xml until prior 0.7 // It is used as an indicator that uuid's are used to identify terminals bool element_found = false; @@ -1114,7 +1112,8 @@ Terminal* findTerminal(int conductor_index, if (element->uuid() != element_uuid) continue; element_found = true; - QUuid terminal_uuid = QUuid(f.attribute(terminal_index)); + QUuid terminal_uuid; + QETXML::propertyUuid(conductor, terminal_index, &terminal_uuid); for (auto terminal: element->terminals()) { if (terminal->uuid() != terminal_uuid) continue; @@ -1138,9 +1137,11 @@ Terminal* findTerminal(int conductor_index, << element_uuid << "not found"; } else { - // Backward compatibility. - // Until version 0.7 a generated id is used to link the terminal. - int id_p1 = f.attribute(terminal_index).toInt(); + // Backward compatibility. Until version 0.7 a generated id is used to link the terminal. + int id_p1 = -1; + if (QETXML::propertyInteger(conductor, terminal_index, &id_p1) != QETXML::PropertyFlags::Success) { + qDebug() << "diagramm.cpp:findTerminal(): Reading Id was not successfull"; + } if (!table_adr_id.contains(id_p1)) { qDebug() << "Diagram::fromXml() : terminal id " << id_p1 @@ -1148,6 +1149,7 @@ Terminal* findTerminal(int conductor_index, } else return table_adr_id.value(id_p1); } + qDebug() << "Diagram::findTerminal(): No terminal found."; return nullptr; } @@ -1183,17 +1185,20 @@ Terminal* findTerminal(int conductor_index, \~French true si l'import a reussi, false sinon */ bool Diagram::fromXml(QDomElement &document, - QPointF position, - bool consider_informations, - DiagramContent *content_ptr) { + QPointF position, + bool consider_informations, + DiagramContent *content_ptr) { const QDomElement& root = document; // The first element must be a diagram if (root.tagName() != "diagram") return(false); + qDebug() << "Diagram::fromXml; Diagram: " << root.attribute("title"); + // Read attributes of this diagram if (consider_informations) { // Load border and titleblock + border_and_titleblock.titleBlockFromXml(root); border_and_titleblock.borderFromXml(root); @@ -1205,6 +1210,7 @@ bool Diagram::fromXml(QDomElement &document, defaultConductorProperties.fromXml(default_conductor_elmt); } + // Load the autonum m_conductors_autonum_name = root.attribute("conductorAutonum"); @@ -1258,7 +1264,7 @@ bool Diagram::fromXml(QDomElement &document, if (root.hasAttribute("projectId")) { QETProject *other_project = QETApp::project( root.attribute("projectId", - "-1").toInt()); + "-1").toInt()); /* We try to paste from another project, * then befor paste elements, @@ -1270,8 +1276,8 @@ bool Diagram::fromXml(QDomElement &document, ElementCollectionHandler ech; foreach (QDomElement element_xml, QET::findInDomElement(root, - "elements", - "element")) { + "elements", + "element")) { if (!Element::valideXml(element_xml)) continue; QString type_id = element_xml.attribute("type"); @@ -1281,7 +1287,7 @@ bool Diagram::fromXml(QDomElement &document, type_id, other_project); ech.importFromProject(m_project, - location); + location); } } } @@ -1327,7 +1333,7 @@ bool Diagram::fromXml(QDomElement &document, removeItem(nvel_elmt); delete nvel_elmt; qDebug() << "Diagram::fromXml() : Le chargement des " - "parametres d'un element a echoue"; + "parametres d'un element a echoue"; } else { added_elements << nvel_elmt; } @@ -1336,8 +1342,8 @@ bool Diagram::fromXml(QDomElement &document, // Load text QList added_texts; foreach (QDomElement text_xml, QET::findInDomElement(root, - "inputs", - "input")) { + "inputs", + "input")) { IndependentTextItem *iti = new IndependentTextItem(); iti -> fromXml(text_xml); addItem(iti); @@ -1347,8 +1353,8 @@ bool Diagram::fromXml(QDomElement &document, // Load image QList added_images; foreach (QDomElement image_xml, QET::findInDomElement(root, - "images", - "image")) { + "images", + "image")) { DiagramImageItem *dii = new DiagramImageItem (); dii -> fromXml(image_xml); addItem(dii); @@ -1358,8 +1364,8 @@ bool Diagram::fromXml(QDomElement &document, // Load shape QList added_shapes; foreach (QDomElement shape_xml, QET::findInDomElement(root, - "shapes", - "shape")) { + "shapes", + "shape")) { QetShapeItem *dii = new QetShapeItem (QPointF(0,0)); dii -> fromXml(shape_xml); addItem(dii); @@ -1369,8 +1375,8 @@ bool Diagram::fromXml(QDomElement &document, // Load conductor QList added_conductors; foreach (QDomElement f, QET::findInDomElement(root, - "conductors", - "conductor")) + "conductors", + "conductor")) { if (!Conductor::valideXml(f)) continue; @@ -1379,7 +1385,7 @@ bool Diagram::fromXml(QDomElement &document, Terminal* p1 = findTerminal(1, f, table_adr_id, added_elements); Terminal* p2 = findTerminal(2, f, table_adr_id, added_elements); - if (p1 && p2 && p1 != p2) + if (p1 && p2 && p1 != p2)// TODO: why the condition for unequal is required? { Conductor *c = new Conductor(p1, p2); if (c->isValid()) @@ -1390,13 +1396,15 @@ bool Diagram::fromXml(QDomElement &document, } else delete c; + } else { + qDebug() << "Diagramm::fromXML(): No matching terminals found."; } } //Load tables QVector added_tables; for (auto dom_table - : QETXML::subChild(root, + : QETXML::subChild(root, "tables", QetGraphicsTableItem::xmlTagName())) { @@ -1411,11 +1419,11 @@ bool Diagram::fromXml(QDomElement &document, { QVector added_items; for (auto element : added_elements ) added_items << element; - for (auto cond : added_conductors) added_items << cond; - for (auto shape : added_shapes ) added_items << shape; - for (auto text : added_texts ) added_items << text; - for (auto image : added_images ) added_items << image; - for (auto table : added_tables ) added_items << table; + for (auto cond : added_conductors) added_items << cond; + for (auto shape : added_shapes ) added_items << shape; + for (auto text : added_texts ) added_items << text; + for (auto image : added_images ) added_items << image; + for (auto table : added_tables ) added_items << table; //Get the top left corner of the rectangle that contain all added items QRectF items_rect; @@ -1437,12 +1445,12 @@ bool Diagram::fromXml(QDomElement &document, //Filling of falculatory lists if (content_ptr) { - content_ptr -> m_elements = added_elements; + content_ptr -> m_elements = added_elements; content_ptr -> m_conductors_to_move = added_conductors; #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) // ### Qt 6: remove - content_ptr -> m_text_fields = added_texts.toSet(); - content_ptr -> m_images = added_images.toSet(); - content_ptr -> m_shapes = added_shapes.toSet(); + content_ptr -> m_text_fields = added_texts.toSet(); + content_ptr -> m_images = added_images.toSet(); + content_ptr -> m_shapes = added_shapes.toSet(); #else #if TODO_LIST #pragma message("@TODO remove code for QT 5.14 or later") @@ -1457,7 +1465,7 @@ bool Diagram::fromXml(QDomElement &document, added_shapes.begin(), added_shapes.end()); #endif - content_ptr -> m_tables = added_tables; + content_ptr -> m_tables = added_tables; } adjustSceneRect(); @@ -1475,23 +1483,23 @@ bool Diagram::fromXml(QDomElement &document, @param autonumFolioSeqType */ void Diagram::folioSequentialsFromXml(const QDomElement &root, - QHash* hash, - const QString& folioSeq, - const QString& seq, - const QString& type, - const QString& autonumFolioSeqType) { + QHash* hash, + const QString& folioSeq, + const QString& seq, + const QString& type, + const QString& autonumFolioSeqType) { foreach (QDomElement folioSeqAutoNum, QET::findInDomElement(root, autonumFolioSeqType, folioSeq)) { for(QDomElement folioseq - = folioSeqAutoNum.firstChildElement(type); - !folioseq.isNull(); - folioseq = folioseq.nextSiblingElement(type)) { + = folioSeqAutoNum.firstChildElement(type); + !folioseq.isNull(); + folioseq = folioseq.nextSiblingElement(type)) { QString title = folioseq.attribute("title"); QStringList list; int i = 1; while (folioseq.hasAttribute(seq - + QString::number(i))) { + + QString::number(i))) { list << folioseq.attribute( seq + QString::number(i)); i++; @@ -1529,7 +1537,7 @@ void Diagram::refreshContents() /** @brief Diagram::addItem - Réimplemented from QGraphicsScene::addItem(QGraphicsItem *item) + R??implemented from QGraphicsScene::addItem(QGraphicsItem *item) Do some specific operation if item need it (for exemple an element) @param item */ @@ -1765,10 +1773,10 @@ void Diagram::insertFolioSeqHash(QHash *hash, - const QString& title, - const QString& type, - NumerotationContext *nc) { + QStringList> *hash, + const QString& title, + const QString& type, + NumerotationContext *nc) { int j = 0; for (int i = 0; i < nc->size(); i++) { if (nc->itemAt(i).at(0) == type) { @@ -1793,9 +1801,9 @@ void Diagram::changeZValue(QET::DepthOption option) DiagramContent dc(this); QUndoCommand *undo = new QUndoCommand(tr("Modifier la profondeur")); QList l = dc.items(DiagramContent::SelectedOnly | \ - DiagramContent::Elements | \ - DiagramContent::Shapes | \ - DiagramContent::Images); + DiagramContent::Elements | \ + DiagramContent::Shapes | \ + DiagramContent::Images); QList list; for(QGraphicsItem *item : l) list << item->toGraphicsObject(); @@ -2184,7 +2192,7 @@ void Diagram::adjustSceneRect() { QRectF old_rect = sceneRect(); setSceneRect(border_and_titleblock.borderAndTitleBlockRect().united( - itemsBoundingRect())); + itemsBoundingRect())); update(old_rect.united(sceneRect())); } @@ -2205,20 +2213,20 @@ ExportProperties Diagram::applyProperties( // exports current rendering options // exporte les options de rendu en cours ExportProperties old_properties; - old_properties.draw_grid = displayGrid(); + old_properties.draw_grid = displayGrid(); old_properties.draw_border = border_and_titleblock.borderIsDisplayed(); old_properties.draw_titleblock = border_and_titleblock.titleBlockIsDisplayed(); - old_properties.draw_terminals = drawTerminals(); + old_properties.draw_terminals = drawTerminals(); old_properties.draw_colored_conductors = drawColoredConductors(); old_properties.exported_area = useBorder() ? QET::BorderArea : QET::ElementsArea; // apply the new rendering options // applique les nouvelles options de rendu - setUseBorder (new_properties.exported_area == QET::BorderArea); - setDrawTerminals (new_properties.draw_terminals); + setUseBorder (new_properties.exported_area == QET::BorderArea); + setDrawTerminals (new_properties.draw_terminals); setDrawColoredConductors (new_properties.draw_colored_conductors); - setDisplayGrid (new_properties.draw_grid); + setDisplayGrid (new_properties.draw_grid); border_and_titleblock.displayBorder(new_properties.draw_border); border_and_titleblock.displayTitleBlock (new_properties.draw_titleblock); diff --git a/sources/diagram.h b/sources/diagram.h index f20769cf9..5928747a5 100644 --- a/sources/diagram.h +++ b/sources/diagram.h @@ -96,7 +96,7 @@ class Diagram : public QGraphicsScene /// margin around the diagram static const qreal margin; /// background color of diagram - static QColor background_color; + static QColor background_color; // default value set in cpp file /// Hash containing max values for folio sequential autonums in this diagram QHash m_elmt_unitfolio_max; QHash m_elmt_tenfolio_max; @@ -108,10 +108,10 @@ class Diagram : public QGraphicsScene private: QGraphicsLineItem *conductor_setter_; - ElementsMover m_elements_mover; + ElementsMover m_elements_mover; ElementTextsMover m_element_texts_mover; - QGIManager *qgi_manager_; - QETProject *m_project; + QGIManager *qgi_manager_; + QETProject *m_project; QDomDocument xml_document_; @@ -156,9 +156,9 @@ class Diagram : public QGraphicsScene // methods related to parent project QETProject *project() const; - int folioIndex() const; - void showMe() {emit showDiagram(this);} - bool isReadOnly() const; + int folioIndex() const; + void showMe() {emit showDiagram(this);} + bool isReadOnly() const; // methods related to conductor creation void setConductor(bool); @@ -173,13 +173,13 @@ class Diagram : public QGraphicsScene bool = true, DiagramContent * = nullptr); bool fromXml(QDomDocument &, - QPointF = QPointF(), - bool = true, - DiagramContent * = nullptr); + QPointF = QPointF(), + bool = true, + DiagramContent * = nullptr); bool fromXml(QDomElement &, - QPointF = QPointF(), - bool = true, - DiagramContent * = nullptr); + QPointF = QPointF(), + bool = true, + DiagramContent * = nullptr); void folioSequentialsToXml(QHash*, QDomElement *, @@ -187,17 +187,17 @@ class Diagram : public QGraphicsScene const QString&, QDomDocument *); void folioSequentialsFromXml(const QDomElement&, - QHash*, - const QString&, - const QString&, - const QString&, - const QString&); + QHash*, + const QString&, + const QString&, + const QString&, + const QString&); void refreshContents(); // methods related to graphics items addition/removal on the diagram - virtual void addItem (QGraphicsItem *item); + virtual void addItem (QGraphicsItem *item); virtual void removeItem (QGraphicsItem *item); // methods related to graphics options @@ -253,8 +253,8 @@ class Diagram : public QGraphicsScene const QString& seq, NumerotationContext *nc); void loadFolioSeqHash (QHash *hash, - const QString& title, const QString& seq, - NumerotationContext *nc); + const QString& title, const QString& seq, + NumerotationContext *nc); void changeZValue(QET::DepthOption option); public slots: @@ -262,7 +262,7 @@ class Diagram : public QGraphicsScene void titleChanged(const QString &); void titleBlockTemplateChanged(const QString &); void titleBlockTemplateRemoved(const QString &, - const QString & = QString()); + const QString & = QString()); void setTitleBlockTemplate(const QString &); void updateLabels(); void loadElmtFolioSeq(); @@ -282,6 +282,8 @@ class Diagram : public QGraphicsScene /// from the diagram within elements collection void findElementRequired(const ElementsLocation &); + /// Signal emitted when users wish to edit an element from the diagram + void editElementRequired(const ElementsLocation &); void diagramActivated(); }; Q_DECLARE_METATYPE(Diagram *) diff --git a/sources/diagramcontext.cpp b/sources/diagramcontext.cpp index f0b8eac85..1c13e9131 100644 --- a/sources/diagramcontext.cpp +++ b/sources/diagramcontext.cpp @@ -135,7 +135,7 @@ bool DiagramContext::keyMustShow(const QString &key) const bool DiagramContext::operator==(const DiagramContext &dc) const { - return(m_content == dc.m_content && + return(m_content == dc.m_content && m_content_show == dc.m_content_show); } diff --git a/sources/diagramcontext.h b/sources/diagramcontext.h index 3c9b5f463..c54d5fe51 100644 --- a/sources/diagramcontext.h +++ b/sources/diagramcontext.h @@ -34,23 +34,23 @@ /** * Key for element : - * label -> label or identification of element - * formula -> formula used to create the label (formula is make with variable) - * designation -> exhaustive comment used to explain what the element does. - * description -> exhaustive description used to explain what the element does. - * plant -> the plant assigned to the element - * comment -> a little comment wich can be displayed in the folio - * manufacturer -> the manufacturer of the element - * manufacturer_reference -> the manufacturer reference of the element - * quantity -> quantity of the element - * unity -> unity of the element - * auxiliary1 -> auxiliary 1 of element - * auxiliary2 -> auxiliary 2 of element + * label -> label or identification of element + * formula -> formula used to create the label (formula is make with variable) + * designation -> exhaustive comment used to explain what the element does. + * description -> exhaustive description used to explain what the element does. + * plant -> the plant assigned to the element + * comment -> a little comment wich can be displayed in the folio + * manufacturer -> the manufacturer of the element + * manufacturer_reference -> the manufacturer reference of the element + * quantity -> quantity of the element + * unity -> unity of the element + * auxiliary1 -> auxiliary 1 of element + * auxiliary2 -> auxiliary 2 of element * machine_manufacturer_reference -> reference of the machine manufacturer - * supplier -> the supplier of the element - * function -> the function of element - * location -> the location assigned to the element - * frozenLabel -> label locked at a given time + * supplier -> the supplier of the element + * function -> the function of element + * location -> the location assigned to the element + * frozenLabel -> label locked at a given time * */ class DiagramContext diff --git a/sources/editor/arceditor.cpp b/sources/editor/arceditor.cpp index 113b43c9c..374d12669 100644 --- a/sources/editor/arceditor.cpp +++ b/sources/editor/arceditor.cpp @@ -210,7 +210,7 @@ void ArcEditor::updateArcA() @brief ArcEditor::updateForm Update the value of the widgets */ -void ArcEditor::updateForm() +void ArcEditor::updateFormPriv() { if (!m_part) return; activeConnections(false); diff --git a/sources/editor/arceditor.h b/sources/editor/arceditor.h index 91ac204bc..36781733f 100644 --- a/sources/editor/arceditor.h +++ b/sources/editor/arceditor.h @@ -46,8 +46,6 @@ class ArcEditor : public ElementItemEditor QDoubleSpinBox *x, *y, *h, *v; QSpinBox *angle, *start_angle; bool m_locked; - - QList m_change_connections; // methods public: @@ -59,7 +57,7 @@ class ArcEditor : public ElementItemEditor public slots: void updateArcS(); void updateArcA(); - void updateForm() override; + void updateFormPriv() override; void updateRect(); private: diff --git a/sources/editor/elementitemeditor.cpp b/sources/editor/elementitemeditor.cpp index 540e57f7a..288d2152f 100644 --- a/sources/editor/elementitemeditor.cpp +++ b/sources/editor/elementitemeditor.cpp @@ -42,6 +42,11 @@ ElementScene *ElementItemEditor::elementScene() const return(element_editor -> elementScene()); } +void ElementItemEditor::updateForm() +{ + updateFormPriv(); +} + /// @return la QUndoStack a utiliser pour les annulations QUndoStack &ElementItemEditor::undoStack() const { diff --git a/sources/editor/elementitemeditor.h b/sources/editor/elementitemeditor.h index aa6deca86..ebd5637c4 100644 --- a/sources/editor/elementitemeditor.h +++ b/sources/editor/elementitemeditor.h @@ -55,8 +55,16 @@ class ElementItemEditor : public QWidget virtual CustomElementPart *currentPart() const = 0; virtual QList currentParts() const = 0; - virtual void updateForm() = 0; + /*! + * \brief updateForm + * update the values of the widget + */ + virtual void updateForm(); + private: + virtual void updateFormPriv() = 0; +protected: + QList m_change_connections; // attributes private: QETElementEditor *element_editor; diff --git a/sources/editor/graphicspart/abstractpartellipse.h b/sources/editor/graphicspart/abstractpartellipse.h index afc9f5d72..b2afe067c 100644 --- a/sources/editor/graphicspart/abstractpartellipse.h +++ b/sources/editor/graphicspart/abstractpartellipse.h @@ -79,8 +79,8 @@ class AbstractPartEllipse : public CustomElementGraphicPart protected: QList saved_points_; QRectF m_rect; - qreal m_start_angle; - qreal m_span_angle; + qreal m_start_angle{0}; + qreal m_span_angle{-1440}; QVector m_handler_vector; }; diff --git a/sources/editor/graphicspart/customelementgraphicpart.cpp b/sources/editor/graphicspart/customelementgraphicpart.cpp index e3d2c9291..2f9157489 100644 --- a/sources/editor/graphicspart/customelementgraphicpart.cpp +++ b/sources/editor/graphicspart/customelementgraphicpart.cpp @@ -20,6 +20,8 @@ #include "../../QPropertyUndoCommand/qpropertyundocommand.h" #include "../elementscene.h" +#include "../../qetxml.h" + #include /** @@ -114,7 +116,7 @@ qreal CustomElementGraphicPart::penWeight() const if (_lineweight == NoneWeight || _lineweight == ThinWeight) return 0; else if (_lineweight == NormalWeight) return 1; else if (_lineweight == UltraWeight) return 2; - else if (_lineweight == BigWeight) return 5; + else if (_lineweight == BigWeight) return 5; return 1; } @@ -167,21 +169,21 @@ void CustomElementGraphicPart::stylesToXml(QDomElement &qde) const QString css_like_styles; css_like_styles += "line-style:"; - if (_linestyle == DashedStyle) css_like_styles += "dashed"; - else if (_linestyle == DottedStyle) css_like_styles += "dotted"; + if (_linestyle == DashedStyle) css_like_styles += "dashed"; + else if (_linestyle == DottedStyle) css_like_styles += "dotted"; else if (_linestyle == DashdottedStyle) css_like_styles += "dashdotted"; - else if (_linestyle == NormalStyle) css_like_styles += "normal"; + else if (_linestyle == NormalStyle) css_like_styles += "normal"; css_like_styles += ";line-weight:"; - if (_lineweight == NoneWeight) css_like_styles += "none"; + if (_lineweight == NoneWeight) css_like_styles += "none"; else if (_lineweight == ThinWeight) css_like_styles += "thin"; else if (_lineweight == NormalWeight) css_like_styles += "normal"; else if (_lineweight == UltraWeight) css_like_styles += "hight"; - else if (_lineweight == BigWeight) css_like_styles += "eleve"; + else if (_lineweight == BigWeight) css_like_styles += "eleve"; css_like_styles += ";filling:"; - if (_filling == NoneFilling) css_like_styles += "none"; + if (_filling == NoneFilling) css_like_styles += "none"; else if (_filling == BlackFilling) css_like_styles += "black"; else if (_filling == WhiteFilling) css_like_styles += "white"; else if (_filling == GreenFilling) css_like_styles += "green"; @@ -342,7 +344,7 @@ void CustomElementGraphicPart::stylesToXml(QDomElement &qde) const css_like_styles += ";color:"; - if (_color == WhiteColor) css_like_styles += "white"; + if (_color == WhiteColor) css_like_styles += "white"; else if (_color == BlackColor) css_like_styles += "black"; else if (_color == GreenColor) css_like_styles += "green"; else if (_color == RedColor) css_like_styles += "red"; @@ -497,7 +499,6 @@ void CustomElementGraphicPart::stylesToXml(QDomElement &qde) const else if (_color == HTMLGrayBlackColor) css_like_styles += "HTMLGrayBlack"; else if (_color == NoneColor) css_like_styles += "none"; - qde.setAttribute("style", css_like_styles); qde.setAttribute("antialias", _antialiased ? "true" : "false"); } @@ -512,6 +513,9 @@ void CustomElementGraphicPart::stylesFromXml(const QDomElement &qde) { resetStyles(); + QString style_string; + QETXML::propertyString(qde, "style", &style_string); + //Get the list of pair style/value #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) // ### Qt 6: remove QStringList styles = qde.attribute("style").split(";", QString::SkipEmptyParts); @@ -899,17 +903,17 @@ void CustomElementGraphicPart::applyStylesToQPainter(QPainter &painter) const QBrush brush = painter.brush(); //Apply pen style - if (_linestyle == DashedStyle) pen.setStyle(Qt::DashLine); + if (_linestyle == DashedStyle) pen.setStyle(Qt::DashLine); else if (_linestyle == DashdottedStyle) pen.setStyle(Qt::DashDotLine); - else if (_linestyle == DottedStyle) pen.setStyle(Qt::DotLine); - else if (_linestyle == NormalStyle) pen.setStyle(Qt::SolidLine); + else if (_linestyle == DottedStyle) pen.setStyle(Qt::DotLine); + else if (_linestyle == NormalStyle) pen.setStyle(Qt::SolidLine); //Apply pen width - if (_lineweight == NoneWeight) pen.setColor(QColor(0, 0, 0, 0)); + if (_lineweight == NoneWeight) pen.setColor(QColor(0, 0, 0, 0)); else if (_lineweight == ThinWeight) pen.setWidth(0); else if (_lineweight == NormalWeight) pen.setWidthF(1.0); else if (_lineweight == UltraWeight) pen.setWidthF(2.0); - else if (_lineweight == BigWeight) pen.setWidthF(5.0); + else if (_lineweight == BigWeight) pen.setWidthF(5.0); //Apply brush color if (_filling == NoneFilling) brush.setStyle(Qt::NoBrush); @@ -920,7 +924,7 @@ void CustomElementGraphicPart::applyStylesToQPainter(QPainter &painter) const else { brush.setStyle(Qt::SolidPattern); - if (_filling == BlackFilling) brush.setColor(Qt::black); + if (_filling == BlackFilling) brush.setColor(Qt::black); else if (_filling == WhiteFilling) brush.setColor(Qt::white); else if (_filling == GreenFilling) brush.setColor(Qt::green); else if (_filling == RedFilling) brush.setColor(Qt::red); @@ -1076,7 +1080,7 @@ void CustomElementGraphicPart::applyStylesToQPainter(QPainter &painter) const } //Apply pen color - if (_color == WhiteColor) pen.setColor(QColor(255, 255, 255, pen.color().alpha())); + if (_color == WhiteColor) pen.setColor(QColor(255, 255, 255, pen.color().alpha())); else if (_color == BlackColor) pen.setColor(QColor( 0, 0, 0, pen.color().alpha())); else if (_color == GreenColor) pen.setColor(QColor(Qt::green)); else if (_color == RedColor) pen.setColor(QColor(Qt::red)); @@ -1232,8 +1236,8 @@ void CustomElementGraphicPart::applyStylesToQPainter(QPainter &painter) const else if (_color == NoneColor) pen.setBrush(Qt::transparent); //Apply antialiasing - painter.setRenderHint(QPainter::Antialiasing, _antialiased); - painter.setRenderHint(QPainter::TextAntialiasing, _antialiased); + painter.setRenderHint(QPainter::Antialiasing, _antialiased); + painter.setRenderHint(QPainter::TextAntialiasing, _antialiased); painter.setRenderHint(QPainter::SmoothPixmapTransform, _antialiased); painter.setPen(pen); @@ -1312,7 +1316,7 @@ void CustomElementGraphicPart::mouseReleaseEvent(QGraphicsSceneMouseEvent *event if((event->button() & Qt::LeftButton) && (flags() & QGraphicsItem::ItemIsMovable) && m_origin_pos != pos()) { QPropertyUndoCommand *undo = new QPropertyUndoCommand(this, "pos", QVariant(m_origin_pos), QVariant(pos())); - undo->setText(tr("Déplacer une primitive")); + undo->setText(tr("D??placer une primitive")); undo->enableAnimation(); elementScene()->undoStack().push(undo); } diff --git a/sources/editor/graphicspart/customelementgraphicpart.h b/sources/editor/graphicspart/customelementgraphicpart.h index 6b1084c67..0b7f0c70a 100644 --- a/sources/editor/graphicspart/customelementgraphicpart.h +++ b/sources/editor/graphicspart/customelementgraphicpart.h @@ -40,9 +40,9 @@ class CustomElementGraphicPart : public QGraphicsObject, public CustomElementPar Q_PROPERTY(LineStyle line_style READ lineStyle WRITE setLineStyle) Q_PROPERTY(LineWeight line_weight READ lineWeight WRITE setLineWeight) - Q_PROPERTY(Filling filling READ filling WRITE setFilling) - Q_PROPERTY(Color color READ color WRITE setColor) - Q_PROPERTY(bool antialias READ antialiased WRITE setAntialiased) + Q_PROPERTY(Filling filling READ filling WRITE setFilling) + Q_PROPERTY(Color color READ color WRITE setColor) + Q_PROPERTY(bool antialias READ antialiased WRITE setAntialiased) public: //Line style @@ -62,122 +62,122 @@ class CustomElementGraphicPart : public QGraphicsObject, public CustomElementPar //Filling color of the part : NoneFilling -> No filling (i.e. transparent) enum Filling { NoneFilling, BlackFilling, WhiteFilling, - GreenFilling, RedFilling, BlueFilling, - GrayFilling, BrunFilling, YellowFilling, - CyanFilling, MagentaFilling, LightgrayFilling, - OrangeFilling, PurpleFilling, - HTMLPinkPinkFilling, HTMLPinkLightPinkFilling, - HTMLPinkHotPinkFilling, HTMLPinkDeepPinkFilling, - HTMLPinkPaleVioletRedFilling, - HTMLPinkMediumVioletRedFilling, - HTMLRedLightSalmonFilling, HTMLRedSalmonFilling, - HTMLRedDarkSalmonFilling, - HTMLRedLightCoralFilling, - HTMLRedIndianRedFilling, HTMLRedCrimsonFilling, - HTMLRedFirebrickFilling, HTMLRedDarkRedFilling, - HTMLRedRedFilling, HTMLOrangeOrangeRedFilling, - HTMLOrangeTomatoFilling, HTMLOrangeCoralFilling, - HTMLOrangeDarkOrangeFilling, - HTMLOrangeOrangeFilling, HTMLYellowYellowFilling, - HTMLYellowLightYellowFilling, - HTMLYellowLemonChiffonFilling, - HTMLYellowLightGoldenrodYellowFilling, - HTMLYellowPapayaWhipFilling, - HTMLYellowMoccasinFilling, - HTMLYellowPeachPuffFilling, - HTMLYellowPaleGoldenrodFilling, - HTMLYellowKhakiFilling, - HTMLYellowDarkKhakiFilling, - HTMLYellowGoldFilling, HTMLBrownCornsilkFilling, - HTMLBrownBlanchedAlmondFilling, - HTMLBrownBisqueFilling, - HTMLBrownNavajoWhiteFilling, - HTMLBrownWheatFilling, HTMLBrownBurlywoodFilling, - HTMLBrownTanFilling, HTMLBrownRosyBrownFilling, - HTMLBrownSandyBrownFilling, - HTMLBrownGoldenrodFilling, - HTMLBrownDarkGoldenrodFilling, - HTMLBrownPeruFilling, HTMLBrownChocolateFilling, - HTMLBrownSaddleBrownFilling, - HTMLBrownSiennaFilling, HTMLBrownBrownFilling, - HTMLBrownMaroonFilling, - HTMLGreenDarkOliveGreenFilling, - HTMLGreenOliveFilling, HTMLGreenOliveDrabFilling, - HTMLGreenYellowGreenFilling, - HTMLGreenLimeGreenFilling, HTMLGreenLimeFilling, - HTMLGreenLawnGreenFilling, - HTMLGreenChartreuseFilling, - HTMLGreenGreenYellowFilling, - HTMLGreenSpringGreenFilling, - HTMLGreenMediumSpringGreenFilling, - HTMLGreenLightGreenFilling, - HTMLGreenPaleGreenFilling, - HTMLGreenDarkSeaGreenFilling, - HTMLGreenMediumAquamarineFilling, - HTMLGreenMediumSeaGreenFilling, - HTMLGreenSeaGreenFilling, - HTMLGreenForestGreenFilling, - HTMLGreenGreenFilling, HTMLGreenDarkGreenFilling, - HTMLCyanAquaFilling, HTMLCyanCyanFilling, - HTMLCyanLightCyanFilling, - HTMLCyanPaleTurquoiseFilling, - HTMLCyanAquamarineFilling, - HTMLCyanTurquoiseFilling, - HTMLCyanMediumTurquoiseFilling, - HTMLCyanDarkTurquoiseFilling, - HTMLCyanLightSeaGreenFilling, - HTMLCyanCadetBlueFilling, - HTMLCyanDarkCyanFilling, HTMLCyanTealFilling, - HTMLBlueLightSteelBlueFilling, - HTMLBluePowderBlueFilling, - HTMLBlueLightBlueFilling, HTMLBlueSkyBlueFilling, - HTMLBlueLightSkyBlueFilling, - HTMLBlueDeepSkyBlueFilling, - HTMLBlueDodgerBlueFilling, - HTMLBlueCornflowerBlueFilling, - HTMLBlueSteelBlueFilling, - HTMLBlueRoyalBlueFilling, HTMLBlueBlueFilling, - HTMLBlueMediumBlueFilling, - HTMLBlueDarkBlueFilling, HTMLBlueNavyFilling, - HTMLBlueMidnightBlueFilling, - HTMLPurpleLavenderFilling, - HTMLPurpleThistleFilling, HTMLPurplePlumFilling, - HTMLPurpleVioletFilling, HTMLPurpleOrchidFilling, - HTMLPurpleFuchsiaFilling, - HTMLPurpleMagentaFilling, - HTMLPurpleMediumOrchidFilling, - HTMLPurpleMediumPurpleFilling, - HTMLPurpleBlueVioletFilling, - HTMLPurpleDarkVioletFilling, - HTMLPurpleDarkOrchidFilling, - HTMLPurpleDarkMagentaFilling, - HTMLPurplePurpleFilling, HTMLPurpleIndigoFilling, - HTMLPurpleDarkSlateBlueFilling, - HTMLPurpleSlateBlueFilling, - HTMLPurpleMediumSlateBlueFilling, - HTMLWhiteWhiteFilling, HTMLWhiteSnowFilling, - HTMLWhiteHoneydewFilling, - HTMLWhiteMintCreamFilling, HTMLWhiteAzureFilling, - HTMLWhiteAliceBlueFilling, - HTMLWhiteGhostWhiteFilling, - HTMLWhiteWhiteSmokeFilling, - HTMLWhiteSeashellFilling, HTMLWhiteBeigeFilling, - HTMLWhiteOldLaceFilling, - HTMLWhiteFloralWhiteFilling, - HTMLWhiteIvoryFilling, - HTMLWhiteAntiqueWhiteFilling, - HTMLWhiteLinenFilling, - HTMLWhiteLavenderBlushFilling, - HTMLWhiteMistyRoseFilling, - HTMLGrayGainsboroFilling, - HTMLGrayLightGrayFilling, HTMLGraySilverFilling, - HTMLGrayDarkGrayFilling, HTMLGrayGrayFilling, - HTMLGrayDimGrayFilling, - HTMLGrayLightSlateGrayFilling, - HTMLGraySlateGrayFilling, - HTMLGrayDarkSlateGrayFilling, - HTMLGrayBlackFilling, HorFilling, VerFilling, - BdiagFilling, FdiagFilling}; + GreenFilling, RedFilling, BlueFilling, + GrayFilling, BrunFilling, YellowFilling, + CyanFilling, MagentaFilling, LightgrayFilling, + OrangeFilling, PurpleFilling, + HTMLPinkPinkFilling, HTMLPinkLightPinkFilling, + HTMLPinkHotPinkFilling, HTMLPinkDeepPinkFilling, + HTMLPinkPaleVioletRedFilling, + HTMLPinkMediumVioletRedFilling, + HTMLRedLightSalmonFilling, HTMLRedSalmonFilling, + HTMLRedDarkSalmonFilling, + HTMLRedLightCoralFilling, + HTMLRedIndianRedFilling, HTMLRedCrimsonFilling, + HTMLRedFirebrickFilling, HTMLRedDarkRedFilling, + HTMLRedRedFilling, HTMLOrangeOrangeRedFilling, + HTMLOrangeTomatoFilling, HTMLOrangeCoralFilling, + HTMLOrangeDarkOrangeFilling, + HTMLOrangeOrangeFilling, HTMLYellowYellowFilling, + HTMLYellowLightYellowFilling, + HTMLYellowLemonChiffonFilling, + HTMLYellowLightGoldenrodYellowFilling, + HTMLYellowPapayaWhipFilling, + HTMLYellowMoccasinFilling, + HTMLYellowPeachPuffFilling, + HTMLYellowPaleGoldenrodFilling, + HTMLYellowKhakiFilling, + HTMLYellowDarkKhakiFilling, + HTMLYellowGoldFilling, HTMLBrownCornsilkFilling, + HTMLBrownBlanchedAlmondFilling, + HTMLBrownBisqueFilling, + HTMLBrownNavajoWhiteFilling, + HTMLBrownWheatFilling, HTMLBrownBurlywoodFilling, + HTMLBrownTanFilling, HTMLBrownRosyBrownFilling, + HTMLBrownSandyBrownFilling, + HTMLBrownGoldenrodFilling, + HTMLBrownDarkGoldenrodFilling, + HTMLBrownPeruFilling, HTMLBrownChocolateFilling, + HTMLBrownSaddleBrownFilling, + HTMLBrownSiennaFilling, HTMLBrownBrownFilling, + HTMLBrownMaroonFilling, + HTMLGreenDarkOliveGreenFilling, + HTMLGreenOliveFilling, HTMLGreenOliveDrabFilling, + HTMLGreenYellowGreenFilling, + HTMLGreenLimeGreenFilling, HTMLGreenLimeFilling, + HTMLGreenLawnGreenFilling, + HTMLGreenChartreuseFilling, + HTMLGreenGreenYellowFilling, + HTMLGreenSpringGreenFilling, + HTMLGreenMediumSpringGreenFilling, + HTMLGreenLightGreenFilling, + HTMLGreenPaleGreenFilling, + HTMLGreenDarkSeaGreenFilling, + HTMLGreenMediumAquamarineFilling, + HTMLGreenMediumSeaGreenFilling, + HTMLGreenSeaGreenFilling, + HTMLGreenForestGreenFilling, + HTMLGreenGreenFilling, HTMLGreenDarkGreenFilling, + HTMLCyanAquaFilling, HTMLCyanCyanFilling, + HTMLCyanLightCyanFilling, + HTMLCyanPaleTurquoiseFilling, + HTMLCyanAquamarineFilling, + HTMLCyanTurquoiseFilling, + HTMLCyanMediumTurquoiseFilling, + HTMLCyanDarkTurquoiseFilling, + HTMLCyanLightSeaGreenFilling, + HTMLCyanCadetBlueFilling, + HTMLCyanDarkCyanFilling, HTMLCyanTealFilling, + HTMLBlueLightSteelBlueFilling, + HTMLBluePowderBlueFilling, + HTMLBlueLightBlueFilling, HTMLBlueSkyBlueFilling, + HTMLBlueLightSkyBlueFilling, + HTMLBlueDeepSkyBlueFilling, + HTMLBlueDodgerBlueFilling, + HTMLBlueCornflowerBlueFilling, + HTMLBlueSteelBlueFilling, + HTMLBlueRoyalBlueFilling, HTMLBlueBlueFilling, + HTMLBlueMediumBlueFilling, + HTMLBlueDarkBlueFilling, HTMLBlueNavyFilling, + HTMLBlueMidnightBlueFilling, + HTMLPurpleLavenderFilling, + HTMLPurpleThistleFilling, HTMLPurplePlumFilling, + HTMLPurpleVioletFilling, HTMLPurpleOrchidFilling, + HTMLPurpleFuchsiaFilling, + HTMLPurpleMagentaFilling, + HTMLPurpleMediumOrchidFilling, + HTMLPurpleMediumPurpleFilling, + HTMLPurpleBlueVioletFilling, + HTMLPurpleDarkVioletFilling, + HTMLPurpleDarkOrchidFilling, + HTMLPurpleDarkMagentaFilling, + HTMLPurplePurpleFilling, HTMLPurpleIndigoFilling, + HTMLPurpleDarkSlateBlueFilling, + HTMLPurpleSlateBlueFilling, + HTMLPurpleMediumSlateBlueFilling, + HTMLWhiteWhiteFilling, HTMLWhiteSnowFilling, + HTMLWhiteHoneydewFilling, + HTMLWhiteMintCreamFilling, HTMLWhiteAzureFilling, + HTMLWhiteAliceBlueFilling, + HTMLWhiteGhostWhiteFilling, + HTMLWhiteWhiteSmokeFilling, + HTMLWhiteSeashellFilling, HTMLWhiteBeigeFilling, + HTMLWhiteOldLaceFilling, + HTMLWhiteFloralWhiteFilling, + HTMLWhiteIvoryFilling, + HTMLWhiteAntiqueWhiteFilling, + HTMLWhiteLinenFilling, + HTMLWhiteLavenderBlushFilling, + HTMLWhiteMistyRoseFilling, + HTMLGrayGainsboroFilling, + HTMLGrayLightGrayFilling, HTMLGraySilverFilling, + HTMLGrayDarkGrayFilling, HTMLGrayGrayFilling, + HTMLGrayDimGrayFilling, + HTMLGrayLightSlateGrayFilling, + HTMLGraySlateGrayFilling, + HTMLGrayDarkSlateGrayFilling, + HTMLGrayBlackFilling, HorFilling, VerFilling, + BdiagFilling, FdiagFilling}; Q_ENUM (Filling) //Line color @@ -269,18 +269,18 @@ class CustomElementGraphicPart : public QGraphicsObject, public CustomElementPar ~CustomElementGraphicPart() override; static void drawCross (const QPointF ¢er, - QPainter *painter); + QPainter *painter); //Getter and setter - LineStyle lineStyle () const {return _linestyle;} - void setLineStyle (const LineStyle ls); + LineStyle lineStyle () const {return _linestyle;} + void setLineStyle (const LineStyle ls); - LineWeight lineWeight () const {return _lineweight;} - void setLineWeight (const LineWeight lw); - qreal penWeight () const; + LineWeight lineWeight () const {return _lineweight;} + void setLineWeight (const LineWeight lw); + qreal penWeight () const; Filling filling () const {return _filling;} - void setFilling(const Filling f); + void setFilling(const Filling f); Color color () const {return _color;} void setColor(const Color c); @@ -299,11 +299,11 @@ class CustomElementGraphicPart : public QGraphicsObject, public CustomElementPar virtual QPainterPath shadowShape ()const = 0; virtual void setHandlerColor(QPointF /*pos*/, - const QColor &/*color*/) {} + const QColor &/*color*/) {} virtual void resetAllHandlerColor() {} protected: - void stylesToXml (QDomElement &) const; + void stylesToXml (QDomElement &) const; void stylesFromXml(const QDomElement &); void resetStyles (); void applyStylesToQPainter(QPainter &) const; diff --git a/sources/editor/graphicspart/customelementpart.h b/sources/editor/graphicspart/customelementpart.h index 04d582392..c1a7d3ce3 100644 --- a/sources/editor/graphicspart/customelementpart.h +++ b/sources/editor/graphicspart/customelementpart.h @@ -19,6 +19,7 @@ #define CUSTOM_ELEMENT_PART_H #include "../../qet.h" +#include "../../properties/propertiesinterface.h" class CustomElement; class ElementPrimitiveDecorator; @@ -37,7 +38,7 @@ class QGraphicsSceneMouseEvent; there is no point for those classes to store their visual representation with anything more complex than a QImage. */ -class CustomElementPart { +class CustomElementPart: public PropertiesInterface { // constructors, destructor public: /** @@ -61,14 +62,6 @@ class CustomElementPart { // methods public: - /** - Load the primitive from an XML element that describes it - */ - virtual void fromXml(const QDomElement &) = 0; - /** - Export the primitive as an XML element - */ - virtual const QDomElement toXml(QDomDocument &) const = 0; /** Set a specific property of the primitive */ @@ -92,7 +85,7 @@ class CustomElementPart { Make this part fit into the provided rectangle. */ virtual void handleUserTransformation(const QRectF &, - const QRectF &) = 0; + const QRectF &) = 0; /// @return a pointer to the parent element editor virtual QETElementEditor *elementEditor() const; /** diff --git a/sources/editor/graphicspart/partarc.cpp b/sources/editor/graphicspart/partarc.cpp index a5e3e70dd..f51e8edb2 100644 --- a/sources/editor/graphicspart/partarc.cpp +++ b/sources/editor/graphicspart/partarc.cpp @@ -22,6 +22,8 @@ #include "../../QetGraphicsItemModeler/qetgraphicshandlerutility.h" #include "../elementscene.h" +#include "../../qetxml.h" + /** @brief PartArc::PartArc Constructor @@ -29,10 +31,9 @@ @param parent : parent item */ PartArc::PartArc(QETElementEditor *editor, QGraphicsItem *parent) : - AbstractPartEllipse(editor, parent) + AbstractPartEllipse(editor, parent) { - m_start_angle = 0; - m_span_angle = -1440; + setTagName("arc"); } /** @@ -102,19 +103,18 @@ void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, @param xml_document : Xml document to use for create the xml element. @return : an xml element that describe this arc */ -const QDomElement PartArc::toXml(QDomDocument &xml_document) const +void PartArc::toXmlPriv(QDomElement& xml_element) const { - QDomElement xml_element = xml_document.createElement("arc"); - QPointF top_left(sceneTopLeft()); - xml_element.setAttribute("x", QString("%1").arg(top_left.x())); - xml_element.setAttribute("y", QString("%1").arg(top_left.y())); - xml_element.setAttribute("width", QString("%1").arg(rect().width())); - xml_element.setAttribute("height", QString("%1").arg(rect().height())); - //to maintain compatibility with the previous version, we write the angle in degrees. - xml_element.setAttribute("start", QString("%1").arg(m_start_angle / 16)); - xml_element.setAttribute("angle", QString("%1").arg(m_span_angle / 16)); - stylesToXml(xml_element); - return(xml_element); + xml_element.setTagName("arc"); + QPointF top_left(sceneTopLeft()); + xml_element.setAttribute("x", QString("%1").arg(top_left.x())); + xml_element.setAttribute("y", QString("%1").arg(top_left.y())); + xml_element.setAttribute("width", QString("%1").arg(rect().width())); + xml_element.setAttribute("height", QString("%1").arg(rect().height())); + //to maintain compatibility with the previous version, we write the angle in degrees. + xml_element.setAttribute("start", QString("%1").arg(m_start_angle / 16)); + xml_element.setAttribute("angle", QString("%1").arg(m_span_angle / 16)); + stylesToXml(xml_element); } /** @@ -122,15 +122,41 @@ const QDomElement PartArc::toXml(QDomDocument &xml_document) const Import the properties of this arc from a xml element. @param qde : Xml document to use. */ -void PartArc::fromXml(const QDomElement &qde) { +bool PartArc::fromXmlPriv(const QDomElement &qde) { stylesFromXml(qde); - m_rect = QRectF(mapFromScene(qde.attribute("x", "0").toDouble(), - qde.attribute("y", "0").toDouble()), - QSizeF(qde.attribute("width", "0").toDouble(), - qde.attribute("height", "0").toDouble()) ); - m_start_angle = qde.attribute("start", "0").toDouble() * 16; - m_span_angle = qde.attribute("angle", "-1440").toDouble() * 16; + double x=0, y=0, w=0, h=0; + if (QETXML::propertyDouble(qde, "x", &x) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(qde, "y", &y) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(qde, "width", &w) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(qde, "height", &h) == QETXML::PropertyFlags::NoValidConversion) + return false; + + m_rect = QRectF(mapFromScene(x, y), QSizeF(w, h) ); + + m_start_angle = 0; + if (QETXML::propertyDouble(qde, "start", &m_start_angle) == QETXML::PropertyFlags::NoValidConversion) + return false; + m_start_angle *= 16; + + m_span_angle = -1440; + if (QETXML::propertyDouble(qde, "angle", &m_span_angle) == QETXML::PropertyFlags::NoValidConversion) + return false; + m_span_angle *= 16; + + return true; +} + +bool PartArc::valideXml(QDomElement& element) { + + if (QETXML::propertyDouble(element, "x") == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(element, "y") == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(element, "width") == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(element, "height") == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(element, "start") == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(element, "angle") == QETXML::PropertyFlags::NoValidConversion) + return false; + return true; } /** diff --git a/sources/editor/graphicspart/partarc.h b/sources/editor/graphicspart/partarc.h index 1186c10c5..65c926335 100644 --- a/sources/editor/graphicspart/partarc.h +++ b/sources/editor/graphicspart/partarc.h @@ -49,10 +49,13 @@ class PartArc : public AbstractPartEllipse void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = nullptr) override; //Name and XML - QString name() const override { return(QObject::tr("arc", "element part name")); } + QString name() const override { return(QObject::tr("arc", "element part name")); } QString xmlName() const override { return(QString("arc")); } - const QDomElement toXml (QDomDocument &) const override; - void fromXml (const QDomElement &) override; + void toXmlPriv(QDomElement&xml_element) const override; + bool fromXmlPriv (const QDomElement &) override; + static bool valideXml(QDomElement& element); + void toSettings(QSettings &,const QString & = QString()) const override {/*TODO: implement*/} + void fromSettings(QSettings &,const QString & = QString()) override{/*TODO: implement*/} QPainterPath shape() const override; QPainterPath shadowShape() const override; @@ -70,7 +73,7 @@ class PartArc : public AbstractPartEllipse void switchResizeMode(); void adjusteHandlerPos(); void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); - void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); + void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); void sceneSelectionChanged (); diff --git a/sources/editor/graphicspart/partdynamictextfield.cpp b/sources/editor/graphicspart/partdynamictextfield.cpp index cac068fe4..d3b292865 100644 --- a/sources/editor/graphicspart/partdynamictextfield.cpp +++ b/sources/editor/graphicspart/partdynamictextfield.cpp @@ -21,6 +21,8 @@ #include "../../qetapp.h" #include "../elementscene.h" +#include "../../qetxml.h" + #include #include #include @@ -30,6 +32,7 @@ PartDynamicTextField::PartDynamicTextField(QETElementEditor *editor, QGraphicsIt CustomElementPart(editor), m_uuid(QUuid::createUuid()) { + setTagName(xmlName()); setDefaultTextColor(Qt::black); setFont(QETApp::dynamicTextsItemFont()); QSettings settings; @@ -93,88 +96,91 @@ void PartDynamicTextField::handleUserTransformation( @param dom_doc @return */ -const QDomElement PartDynamicTextField::toXml(QDomDocument &dom_doc) const +void PartDynamicTextField::toXmlPriv(QDomElement& root_element) const { - QDomElement root_element = dom_doc.createElement(xmlName()); - root_element.setAttribute("x", QString::number(pos().x())); - root_element.setAttribute("y", QString::number(pos().y())); - root_element.setAttribute("z", QString::number(zValue())); - root_element.setAttribute("rotation", QString::number(QET::correctAngle(rotation()))); - root_element.setAttribute("font", font().toString()); - root_element.setAttribute("uuid", m_uuid.toString()); - root_element.setAttribute("frame", m_frame? "true" : "false"); - root_element.setAttribute("text_width", QString::number(m_text_width)); + root_element.setAttribute("x", QString::number(pos().x())); + root_element.setAttribute("y", QString::number(pos().y())); + root_element.setAttribute("z", QString::number(zValue())); + root_element.setAttribute("rotation", QString::number(QET::correctAngle(rotation()))); + root_element.setAttribute("font", font().toString()); + root_element.setAttribute("uuid", m_uuid.toString()); + root_element.setAttribute("frame", m_frame? "true" : "false"); + root_element.setAttribute("text_width", QString::number(m_text_width)); - QMetaEnum me = DynamicElementTextItem::textFromMetaEnum(); - root_element.setAttribute("text_from", me.valueToKey(m_text_from)); + QMetaEnum me = DynamicElementTextItem::textFromMetaEnum(); + root_element.setAttribute("text_from", me.valueToKey(m_text_from)); - me = QMetaEnum::fromType(); - if(this -> alignment() &Qt::AlignRight) - root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignRight)); - else if(this -> alignment() &Qt::AlignLeft) - root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignLeft)); - else if(this -> alignment() &Qt::AlignHCenter) - root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignHCenter)); + me = QMetaEnum::fromType(); + if(this -> alignment() &Qt::AlignRight) + root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignRight)); + else if(this -> alignment() &Qt::AlignLeft) + root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignLeft)); + else if(this -> alignment() &Qt::AlignHCenter) + root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignHCenter)); - if(this -> alignment() &Qt::AlignBottom) - root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignBottom)); - else if(this -> alignment() & Qt::AlignTop) - root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignTop)); - else if(this -> alignment() &Qt::AlignVCenter) - root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignVCenter)); + if(this -> alignment() &Qt::AlignBottom) + root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignBottom)); + else if(this -> alignment() & Qt::AlignTop) + root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignTop)); + else if(this -> alignment() &Qt::AlignVCenter) + root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignVCenter)); - QDomElement dom_text = dom_doc.createElement("text"); - dom_text.appendChild(dom_doc.createTextNode(toPlainText())); - root_element.appendChild(dom_text); + QDomElement dom_text = root_element.ownerDocument().createElement("text"); + dom_text.appendChild(root_element.ownerDocument().createTextNode(toPlainText())); + root_element.appendChild(dom_text); - //Info name - if(!m_info_name.isEmpty()) { - QDomElement dom_info_name = dom_doc.createElement("info_name"); - dom_info_name.appendChild(dom_doc.createTextNode(m_info_name)); - root_element.appendChild(dom_info_name); - } + //Info name + if(!m_info_name.isEmpty()) { + QDomElement dom_info_name = root_element.ownerDocument().createElement("info_name"); + dom_info_name.appendChild(root_element.ownerDocument().createTextNode(m_info_name)); + root_element.appendChild(dom_info_name); + } - //Composite text - if(!m_composite_text.isEmpty()) { - QDomElement dom_comp_text = dom_doc.createElement("composite_text"); - dom_comp_text.appendChild(dom_doc.createTextNode(m_composite_text)); - root_element.appendChild(dom_comp_text); - } + //Composite text + if(!m_composite_text.isEmpty()) { + QDomElement dom_comp_text = root_element.ownerDocument().createElement("composite_text"); + dom_comp_text.appendChild(root_element.ownerDocument().createTextNode(m_composite_text)); + root_element.appendChild(dom_comp_text); + } - //Color - if(color() != QColor(Qt::black)) { - QDomElement dom_color = dom_doc.createElement("color"); - dom_color.appendChild(dom_doc.createTextNode(color().name())); - root_element.appendChild(dom_color); - } - - return root_element; + //Color + if(color() != QColor(Qt::black)) { + QDomElement dom_color = root_element.ownerDocument().createElement("color"); + dom_color.appendChild(root_element.ownerDocument().createTextNode(color().name())); + root_element.appendChild(dom_color); + } } /** @brief PartDynamicTextField::fromXml @param dom_elmt */ -void PartDynamicTextField::fromXml(const QDomElement &dom_elmt) { +bool PartDynamicTextField::fromXmlPriv(const QDomElement &dom_elmt) +{ if (dom_elmt.tagName() != xmlName()) { qDebug() << "PartDynamicTextField::fromXml : Wrong tagg name"; - return; + return false; } - QGraphicsTextItem::setPos( - dom_elmt.attribute("x", QString::number(0)).toDouble(), - dom_elmt.attribute("y", QString::number(0)).toDouble() - ); - setZValue(dom_elmt.attribute("z", QString::number(zValue())).toDouble()); - QGraphicsTextItem::setRotation(dom_elmt.attribute("rotation", QString::number(0)).toDouble()); + double x=0, y=0, z=0, rot=0; + if (QETXML::propertyDouble(dom_elmt, "x", &x) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(dom_elmt, "y", &y) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(dom_elmt, "z", &z) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(dom_elmt, "rotation", &rot) == QETXML::PropertyFlags::NoValidConversion) + return false; + + QGraphicsTextItem::setPos(x, y); + setZValue(z); + QGraphicsTextItem::setRotation(rot); - if (dom_elmt.hasAttribute("font")) { + QString font; + if (QETXML::propertyString(dom_elmt, "font", &font) == QETXML::PropertyFlags::Success) + { QFont font_; - font_.fromString(dom_elmt.attribute("font")); + font_.fromString(font); setFont(font_); - } - else { + } else { //Keep compatibility TODO remove in futur #if TODO_LIST #pragma message("@TODO remove in futur") #endif @@ -182,19 +188,24 @@ void PartDynamicTextField::fromXml(const QDomElement &dom_elmt) { setFont(QETApp::dynamicTextsItemFont(9)); } - m_uuid = QUuid(dom_elmt.attribute("uuid", QUuid::createUuid().toString())); - setFrame(dom_elmt.attribute("frame", "false") == "true"? true : false); - setTextWidth(dom_elmt.attribute("text_width", QString::number(-1)).toDouble()); + QETXML::propertyUuid(dom_elmt, "uuid", &m_uuid); + bool frame; + QETXML::propertyBool(dom_elmt, "frame", &frame); + + double text_width=-1; + QETXML::propertyDouble(dom_elmt, "text_width", &text_width); + setTextWidth(text_width); QMetaEnum me = DynamicElementTextItem::textFromMetaEnum(); - m_text_from = DynamicElementTextItem::TextFrom( - me.keyToValue(dom_elmt.attribute("text_from").toStdString().data())); + QString text_from; + QETXML::propertyString(dom_elmt, "text_from", &text_from); + m_text_from = DynamicElementTextItem::TextFrom(me.keyToValue(text_from.toStdString().data())); me = QMetaEnum::fromType(); - if(dom_elmt.hasAttribute("Halignment")) - setAlignment(Qt::Alignment( - me.keyToValue(dom_elmt.attribute("Halignment").toStdString().data()))); - if(dom_elmt.hasAttribute(("Valignment"))) + QString alignment; + if(QETXML::propertyString(dom_elmt, "Halignment", &alignment) != QETXML::PropertyFlags::NotFound) + setAlignment(Qt::Alignment(me.keyToValue(alignment.toStdString().data()))); + if(QETXML::propertyString(dom_elmt, "Valignment", &alignment) != QETXML::PropertyFlags::NotFound) setAlignment(Qt::Alignment( me.keyToValue(dom_elmt.attribute("Valignment").toStdString().data())) | this -> alignment()); @@ -221,6 +232,29 @@ void PartDynamicTextField::fromXml(const QDomElement &dom_elmt) { QDomElement dom_color = dom_elmt.firstChildElement("color"); if(!dom_color.isNull()) setColor(QColor(dom_color.text())); + + return true; +} + +bool PartDynamicTextField::valideXml(QDomElement& dom_elmt) { + if (QETXML::propertyDouble(dom_elmt, "x") == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(dom_elmt, "y") == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(dom_elmt, "z") == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(dom_elmt, "rotation") == QETXML::PropertyFlags::NoValidConversion) + return false; + + if (QETXML::propertyUuid(dom_elmt, "uuid") == QETXML::PropertyFlags::NoValidConversion) + return false; + + if (QETXML::propertyString(dom_elmt, "text_from")) + return false; + + if(QETXML::propertyString(dom_elmt, "Halignment") == QETXML::PropertyFlags::NotFound) + return false; + if(QETXML::propertyString(dom_elmt, "Valignment") == QETXML::PropertyFlags::NotFound) + return false; + + return true; } /** @@ -464,7 +498,7 @@ void PartDynamicTextField::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { m_origine_pos != pos()) { QPropertyUndoCommand *undo =\ new QPropertyUndoCommand(this, "pos", QVariant(m_origine_pos), QVariant(pos())); - undo -> setText(tr("Déplacer un champ texte")); + undo -> setText(tr("D??placer un champ texte")); undo -> enableAnimation(); elementScene() -> undoStack().push(undo); } diff --git a/sources/editor/graphicspart/partdynamictextfield.h b/sources/editor/graphicspart/partdynamictextfield.h index 9fd02f594..99a0d67f6 100644 --- a/sources/editor/graphicspart/partdynamictextfield.h +++ b/sources/editor/graphicspart/partdynamictextfield.h @@ -75,9 +75,12 @@ class PartDynamicTextField : public QGraphicsTextItem, public CustomElementPart void startUserTransformation(const QRectF &initial_selection_rect) override; void handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) override; - const QDomElement toXml(QDomDocument &dom_doc) const override; - void fromXml(const QDomElement &dom_elmt) override; + void toXmlPriv(QDomElement&root_element) const override; + bool fromXmlPriv(const QDomElement &dom_elmt) override; void fromTextFieldXml(const QDomElement &dom_element); + static bool valideXml(QDomElement& dom_elmt); + void toSettings(QSettings &,const QString & = QString()) const override {/*TODO: implement*/} + void fromSettings(QSettings &,const QString & = QString()) override{/*TODO: implement*/} DynamicElementTextItem::TextFrom textFrom() const; void setTextFrom (DynamicElementTextItem::TextFrom text_from); @@ -116,7 +119,7 @@ class PartDynamicTextField : public QGraphicsTextItem, public CustomElementPart m_info_name, m_composite_text; DynamicElementTextItem::TextFrom m_text_from = DynamicElementTextItem::UserText; - QUuid m_uuid; + QUuid m_uuid{QUuid::createUuid()}; bool m_frame = false, m_first_add = true, m_block_alignment = false; diff --git a/sources/editor/graphicspart/partellipse.cpp b/sources/editor/graphicspart/partellipse.cpp index 6ecdba751..eb6d6a24b 100644 --- a/sources/editor/graphicspart/partellipse.cpp +++ b/sources/editor/graphicspart/partellipse.cpp @@ -22,6 +22,8 @@ #include "../../QetGraphicsItemModeler/qetgraphicshandlerutility.h" #include "../elementscene.h" +#include "../../qetxml.h" + /** @brief PartEllipse::PartEllipse Constructor @@ -79,56 +81,81 @@ void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio } /** - @brief PartEllipse::toXml + @brief PartEllipse::toXmlPriv Export this ellipse in xml - @param xml_document : Xml document to use for create the xml element. @return : an xml element that describe this ellipse */ -const QDomElement PartEllipse::toXml(QDomDocument &xml_document) const +void PartEllipse::toXmlPriv(QDomElement& xml_element) const { - QDomElement xml_element; - if (qFuzzyCompare(rect().width(), rect().height())) - { - xml_element = xml_document.createElement("circle"); - xml_element.setAttribute("diameter", QString("%1").arg(rect().width())); - } - else - { - xml_element = xml_document.createElement("ellipse"); - xml_element.setAttribute("width", QString("%1").arg(rect().width())); - xml_element.setAttribute("height", QString("%1").arg(rect().height())); - } + if (qFuzzyCompare(rect().width(), rect().height())) + { + xml_element.setTagName("circle"); + xml_element.setAttribute("diameter", QString("%1").arg(rect().width())); + } + else + { + xml_element.setTagName("ellipse"); + xml_element.setAttribute("width", QString("%1").arg(rect().width())); + xml_element.setAttribute("height", QString("%1").arg(rect().height())); + } - QPointF top_left(sceneTopLeft()); - xml_element.setAttribute("x", QString("%1").arg(top_left.x())); - xml_element.setAttribute("y", QString("%1").arg(top_left.y())); + QPointF top_left(sceneTopLeft()); + xml_element.setAttribute("x", QString("%1").arg(top_left.x())); + xml_element.setAttribute("y", QString("%1").arg(top_left.y())); - stylesToXml(xml_element); - - return(xml_element); + stylesToXml(xml_element); } /** - @brief PartEllipse::fromXml + @brief PartEllipse::fromXmlPriv Import the properties of this ellipse from a xml element. @param qde : Xml document to use. */ -void PartEllipse::fromXml(const QDomElement &qde) +bool PartEllipse::fromXmlPriv(const QDomElement &qde) { stylesFromXml(qde); - qreal width, height; + double x=0, y=0, width=0, height=0; if (qde.tagName() == "ellipse") { - width = qde.attribute("width", "0").toDouble(); - height = qde.attribute("height", "0").toDouble(); + if (QETXML::propertyDouble(qde, "width", &width) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(qde, "height", &height) == QETXML::PropertyFlags::NoValidConversion) + return false; + } + else { + if (QETXML::propertyDouble(qde, "diameter", &width) == QETXML::PropertyFlags::NoValidConversion) + return false; + height = width; } - else - width = height = qde.attribute("diameter", "0").toDouble(); - m_rect = QRectF(mapFromScene(qde.attribute("x", "0").toDouble(), - qde.attribute("y", "0").toDouble()), - QSizeF(width, height)); + + if (QETXML::propertyDouble(qde, "x", &x) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(qde, "y", &y) == QETXML::PropertyFlags::NoValidConversion) + return false; + + m_rect = QRectF(mapFromScene(x, y), QSizeF(width, height)); + + return true; +} + +bool PartEllipse::valideXml(QDomElement& element) { + if (element.tagName() == "ellipse") + { + if (QETXML::propertyDouble(element, "width") & QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(element, "height") & QETXML::PropertyFlags::NoValidConversion) + return false; + } + else { + if (QETXML::propertyDouble(element, "diameter") & QETXML::PropertyFlags::NoValidConversion) + return false; + } + + + if ((QETXML::propertyDouble(element, "x") & QETXML::PropertyFlags::NoValidConversion) || + (QETXML::propertyDouble(element, "y") & QETXML::PropertyFlags::NoValidConversion)) + return false; + + return true; } /** diff --git a/sources/editor/graphicspart/partellipse.h b/sources/editor/graphicspart/partellipse.h index 0e0bbebae..cd8ccc377 100644 --- a/sources/editor/graphicspart/partellipse.h +++ b/sources/editor/graphicspart/partellipse.h @@ -50,10 +50,13 @@ class PartEllipse : public AbstractPartEllipse void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = nullptr) override; //Name and XML - QString name() const override { return(QObject::tr("ellipse", "element part name")); } + QString name() const override { return(QObject::tr("ellipse", "element part name")); } QString xmlName() const override { return(QString("ellipse")); } - const QDomElement toXml (QDomDocument &) const override; - void fromXml (const QDomElement &) override; + void toXmlPriv(QDomElement&xml_element) const override; + bool fromXmlPriv(const QDomElement &) override; + static bool valideXml(QDomElement& element); + void toSettings(QSettings &,const QString & = QString()) const override {/*TODO: implement*/} + void fromSettings(QSettings &,const QString & = QString()) override{/*TODO: implement*/} QPainterPath shape() const override; QPainterPath shadowShape() const override; void setRect(const QRectF &rect) override {AbstractPartEllipse::setRect(rect); adjusteHandlerPos();} @@ -67,7 +70,7 @@ class PartEllipse : public AbstractPartEllipse void switchResizeMode(); void adjusteHandlerPos(); void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); - void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); + void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); void sceneSelectionChanged (); diff --git a/sources/editor/graphicspart/partline.cpp b/sources/editor/graphicspart/partline.cpp index bc7006e0f..1e80834da 100644 --- a/sources/editor/graphicspart/partline.cpp +++ b/sources/editor/graphicspart/partline.cpp @@ -21,6 +21,8 @@ #include "../../QetGraphicsItemModeler/qetgraphicshandleritem.h" #include "../elementscene.h" +#include "../../qetxml.h" + #include /** @@ -30,13 +32,10 @@ @param parent : parent item */ PartLine::PartLine(QETElementEditor *editor, QGraphicsItem *parent) : - CustomElementGraphicPart(editor, parent), - first_end(Qet::None), - first_length(1.5), - second_end(Qet::None), - second_length(1.5), - m_undo_command(nullptr) -{} + CustomElementGraphicPart(editor, parent) +{ + setTagName("line"); +} /// Destructeur PartLine::~PartLine() @@ -105,28 +104,26 @@ void PartLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, } /** - @brief PartLine::toXml + @brief PartLine::toXmlPriv Export this line in xml @param xml_document : Xml document to use for create the xml element. @return an xml element that describe this line */ -const QDomElement PartLine::toXml(QDomDocument &xml_document) const +void PartLine::toXmlPriv(QDomElement& xml_element) const { - QPointF p1(sceneP1()); - QPointF p2(sceneP2()); + QPointF p1(sceneP1()); + QPointF p2(sceneP2()); - QDomElement xml_element = xml_document.createElement("line"); - xml_element.setAttribute("x1", QString("%1").arg(p1.x())); - xml_element.setAttribute("y1", QString("%1").arg(p1.y())); - xml_element.setAttribute("x2", QString("%1").arg(p2.x())); - xml_element.setAttribute("y2", QString("%1").arg(p2.y())); - xml_element.setAttribute("end1", Qet::endTypeToString(first_end)); - xml_element.setAttribute("length1", QString("%1").arg(first_length)); - xml_element.setAttribute("end2", Qet::endTypeToString(second_end)); - xml_element.setAttribute("length2", QString("%1").arg(second_length)); + xml_element.setAttribute("x1", QString("%1").arg(p1.x())); + xml_element.setAttribute("y1", QString("%1").arg(p1.y())); + xml_element.setAttribute("x2", QString("%1").arg(p2.x())); + xml_element.setAttribute("y2", QString("%1").arg(p2.y())); + xml_element.setAttribute("end1", Qet::endTypeToString(first_end)); + xml_element.setAttribute("length1", QString("%1").arg(first_length)); + xml_element.setAttribute("end2", Qet::endTypeToString(second_end)); + xml_element.setAttribute("length2", QString("%1").arg(second_length)); - stylesToXml(xml_element); - return(xml_element); + stylesToXml(xml_element); } /** @@ -134,17 +131,48 @@ const QDomElement PartLine::toXml(QDomDocument &xml_document) const Import the properties of this line from a xml element. @param qde : Xml document to use */ -void PartLine::fromXml(const QDomElement &qde) { +bool PartLine::fromXmlPriv(const QDomElement &qde) { stylesFromXml(qde); - m_line = QLineF(mapFromScene(qde.attribute("x1", "0").toDouble(), - qde.attribute("y1", "0").toDouble()), - mapFromScene(qde.attribute("x2", "0").toDouble(), - qde.attribute("y2", "0").toDouble())); - first_end = Qet::endTypeFromString(qde.attribute("end1")); - first_length = qde.attribute("length1", "1.5").toDouble(); - second_end = Qet::endTypeFromString(qde.attribute("end2")); - second_length = qde.attribute("length2", "1.5").toDouble(); + double x1 = 0, y1 = 0, x2 = 0, y2 = 0; + if (QETXML::propertyDouble(qde, "x1", &x1) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(qde, "y1", &y1) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(qde, "x2", &x2) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(qde, "y2", &y2) == QETXML::PropertyFlags::NoValidConversion) + return false; + + m_line = QLineF(mapFromScene(x1, y1), + mapFromScene(x2, y2)); + + QString s; + if (QETXML::propertyString(qde, "end1", &s) != QETXML::PropertyFlags::Success) + return false; + first_end = Qet::endTypeFromString(s); + + if (QETXML::propertyString(qde, "end2", &s) != QETXML::PropertyFlags::Success) + return false; + + first_end = Qet::endTypeFromString(s); + + if (QETXML::propertyDouble(qde, "length1", &first_length) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(qde, "length2", &second_length) == QETXML::PropertyFlags::NoValidConversion) + return false; + + return true; +} + +bool PartLine::valideXml(QDomElement& element) const { + if (QETXML::propertyDouble(element, "x1") || + QETXML::propertyDouble(element, "y1") || + QETXML::propertyDouble(element, "x2") || + QETXML::propertyDouble(element, "y2") || + QETXML::propertyString(element, "end1") || + QETXML::propertyString(element, "end2") || + QETXML::propertyDouble(element, "length1") || + QETXML::propertyDouble(element, "length2") ) + return false; + + return true; } /** diff --git a/sources/editor/graphicspart/partline.h b/sources/editor/graphicspart/partline.h index a2fc0ef81..69f61782b 100644 --- a/sources/editor/graphicspart/partline.h +++ b/sources/editor/graphicspart/partline.h @@ -70,8 +70,11 @@ class PartLine : public CustomElementGraphicPart void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = nullptr) override; QString name() const override { return(QObject::tr("ligne", "element part name")); } QString xmlName() const override { return(QString("line")); } - const QDomElement toXml(QDomDocument &) const override; - void fromXml(const QDomElement &) override; + void toXmlPriv(QDomElement&xml_element) const override; + bool fromXmlPriv(const QDomElement &) override; + bool valideXml(QDomElement& element) const; + void toSettings(QSettings &,const QString & = QString()) const override {/*TODO: implement*/} + void fromSettings(QSettings &,const QString & = QString()) override{/*TODO: implement*/} virtual QPointF sceneP1() const; virtual QPointF sceneP2() const; QPainterPath shape() const override; @@ -102,7 +105,7 @@ class PartLine : public CustomElementGraphicPart private: void adjusteHandlerPos(); void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); - void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); + void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); void sceneSelectionChanged (); @@ -114,15 +117,15 @@ class PartLine : public CustomElementGraphicPart QRectF secondEndCircleRect() const; /*****************/ - Qet::EndType first_end; - qreal first_length; + Qet::EndType first_end{Qet::EndType::None}; + qreal first_length{1.5}; - Qet::EndType second_end; - qreal second_length; + Qet::EndType second_end{Qet::EndType::None}; + qreal second_length{1.5}; QList saved_points_; QLineF m_line; int m_vector_index = -1; - QPropertyUndoCommand *m_undo_command; + QPropertyUndoCommand *m_undo_command{nullptr}; QVector m_handler_vector; }; #endif diff --git a/sources/editor/graphicspart/partpolygon.cpp b/sources/editor/graphicspart/partpolygon.cpp index 5e142b374..1d5434ec7 100644 --- a/sources/editor/graphicspart/partpolygon.cpp +++ b/sources/editor/graphicspart/partpolygon.cpp @@ -24,6 +24,8 @@ #include "../elementscene.h" #include "../ui/qetelementeditor.h" +#include "../../qetxml.h" + /** @brief PartPolygon::PartPolygon Constructor @@ -35,6 +37,7 @@ PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent) : m_closed(false), m_undo_command(nullptr) { + setTagName("polygon"); m_insert_point = new QAction(tr("Ajouter un point"), this); m_insert_point->setIcon(QET::Icons::Add); connect(m_insert_point, &QAction::triggered, this, &PartPolygon::insertPoint); @@ -89,50 +92,60 @@ void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio Import the properties of this polygon from a xml element @param qde : Xml document to use */ -void PartPolygon::fromXml(const QDomElement &qde) +bool PartPolygon::fromXmlPriv(const QDomElement &qde) { stylesFromXml(qde); + int error_counter = 0; int i = 1; while(true) { - if (QET::attributeIsAReal(qde, QString("x%1").arg(i)) &&\ - QET::attributeIsAReal(qde, QString("y%1").arg(i))) - ++ i; + if (QETXML::propertyDouble(qde, QString("x%1").arg(i)) == QETXML::PropertyFlags::Success && + QETXML::propertyDouble(qde, QString("y%1").arg(i)) == QETXML::PropertyFlags::Success) + i++; else break; } QPolygonF temp_polygon; + double x, y; for (int j = 1 ; j < i ; ++ j) { - temp_polygon << QPointF(qde.attribute(QString("x%1").arg(j)).toDouble(), - qde.attribute(QString("y%1").arg(j)).toDouble()); + error_counter += QETXML::propertyDouble(qde, QString("x%1").arg(j), &x); + error_counter += QETXML::propertyDouble(qde, QString("y%1").arg(j), &y); + if (error_counter) + return false; + temp_polygon << QPointF(x, y); } m_polygon = temp_polygon; - m_closed = qde.attribute("closed") != "false"; + if (QETXML::propertyBool(qde, "closed", &m_closed) != QETXML::PropertyFlags::Success) + return false; + + return true; } /** - @brief PartPolygon::toXml + @brief PartPolygon::toXmlPriv Export this polygin in xml - @param xml_document : Xml document to use for create the xml element - @return an xml element that describe this polygon + @param e: properties get part of this DomElement */ -const QDomElement PartPolygon::toXml(QDomDocument &xml_document) const +void PartPolygon::toXmlPriv(QDomElement& xml_element) const { - QDomElement xml_element = xml_document.createElement("polygon"); - int i = 1; - foreach(QPointF point, m_polygon) { - point = mapToScene(point); - xml_element.setAttribute(QString("x%1").arg(i), QString("%1").arg(point.x())); - xml_element.setAttribute(QString("y%1").arg(i), QString("%1").arg(point.y())); - ++ i; - } - if (!m_closed) xml_element.setAttribute("closed", "false"); - stylesToXml(xml_element); - return(xml_element); + int i = 1; + foreach(QPointF point, m_polygon) { + point = mapToScene(point); + xml_element.setAttribute(QString("x%1").arg(i), QString("%1").arg(point.x())); + xml_element.setAttribute(QString("y%1").arg(i), QString("%1").arg(point.y())); + ++ i; + } + if (!m_closed) xml_element.setAttribute("closed", "false"); + stylesToXml(xml_element); +} + +bool PartPolygon::valideXml(QDomElement& element) { + // TODO: implement + return true; } /** @@ -525,7 +538,7 @@ void PartPolygon::insertPoint() if(new_polygon != m_polygon) { //Wrap the undo for avoid to merge the undo commands when user add several points. - QUndoCommand *undo = new QUndoCommand(tr("Ajouter un point à un polygone")); + QUndoCommand *undo = new QUndoCommand(tr("Ajouter un point ?? un polygone")); new QPropertyUndoCommand(this, "polygon", m_polygon, new_polygon, undo); elementScene()->undoStack().push(undo); } diff --git a/sources/editor/graphicspart/partpolygon.h b/sources/editor/graphicspart/partpolygon.h index 282f4f126..2f651e133 100644 --- a/sources/editor/graphicspart/partpolygon.h +++ b/sources/editor/graphicspart/partpolygon.h @@ -61,8 +61,12 @@ class PartPolygon : public CustomElementGraphicPart QString name() const override { return(QObject::tr("polygone", "element part name")); } QString xmlName() const override { return(QString("polygon")); } - void fromXml(const QDomElement &) override; - const QDomElement toXml(QDomDocument &) const override; + bool fromXmlPriv(const QDomElement &) override; + void toXmlPriv(QDomElement&xml_element) const override; + static bool valideXml(QDomElement& element); + void toSettings(QSettings &,const QString & = QString()) const override {/*TODO: implement*/} + void fromSettings(QSettings &,const QString & = QString()) override{/*TODO: implement*/} + QPainterPath shape () const override; QPainterPath shadowShape() const override; @@ -77,8 +81,8 @@ class PartPolygon : public CustomElementGraphicPart QPolygonF polygon () const; void setPolygon (const QPolygonF &polygon); - void addPoint (const QPointF &point); - void setLastPoint (const QPointF &point); + void addPoint (const QPointF &point); + void setLastPoint (const QPointF &point); void removeLastPoint (); bool isClosed () const {return m_closed;} @@ -95,7 +99,7 @@ class PartPolygon : public CustomElementGraphicPart private: void adjusteHandlerPos(); void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); - void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); + void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); void sceneSelectionChanged (); @@ -105,7 +109,7 @@ class PartPolygon : public CustomElementGraphicPart void removePoint(); - bool m_closed; + bool m_closed{false}; QList saved_points_; QPolygonF m_polygon; QPropertyUndoCommand *m_undo_command; diff --git a/sources/editor/graphicspart/partrectangle.cpp b/sources/editor/graphicspart/partrectangle.cpp index b9d2c2110..9ca1e0719 100644 --- a/sources/editor/graphicspart/partrectangle.cpp +++ b/sources/editor/graphicspart/partrectangle.cpp @@ -22,6 +22,8 @@ #include "../../QetGraphicsItemModeler/qetgraphicshandlerutility.h" #include "../elementscene.h" +#include "../../qetxml.h" + /** @brief PartRectangle::PartRectangle Constructor @@ -30,7 +32,9 @@ */ PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent) : CustomElementGraphicPart(editor, parent) -{} +{ + setTagName("rect"); +} /** @brief PartRectangle::~PartRectangle @@ -80,35 +84,33 @@ void PartRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt } /** - @brief PartRectangle::toXml + @brief PartRectangle::toXmlPriv Export this rectangle in xml @param xml_document : Xml document to use for create the xml element. @return an xml element that describe this ellipse */ -const QDomElement PartRectangle::toXml(QDomDocument &xml_document) const +void PartRectangle::toXmlPriv(QDomElement& xml_element) const { - QDomElement xml_element = xml_document.createElement("rect"); - QPointF top_left(sceneTopLeft()); - xml_element.setAttribute("x", QString("%1").arg(top_left.x())); - xml_element.setAttribute("y", QString("%1").arg(top_left.y())); - xml_element.setAttribute("width", QString("%1").arg(m_rect.width())); - xml_element.setAttribute("height", QString("%1").arg(m_rect.height())); + QPointF top_left(sceneTopLeft()); + xml_element.setAttribute("x", QString("%1").arg(top_left.x())); + xml_element.setAttribute("y", QString("%1").arg(top_left.y())); + xml_element.setAttribute("width", QString("%1").arg(m_rect.width())); + xml_element.setAttribute("height", QString("%1").arg(m_rect.height())); - QRectF rect = m_rect.normalized(); - qreal x = m_xRadius; - if (x > rect.width()/2) { - x = rect.width()/2; - } - qreal y = m_yRadius; - if (y > rect.height()/2) { - y = rect.height()/2; - } + QRectF rect = m_rect.normalized(); + qreal x = m_xRadius; + if (x > rect.width()/2) { + x = rect.width()/2; + } + qreal y = m_yRadius; + if (y > rect.height()/2) { + y = rect.height()/2; + } - xml_element.setAttribute("rx", QString::number(m_xRadius)); - xml_element.setAttribute("ry", QString::number(m_yRadius)); + xml_element.setAttribute("rx", QString::number(m_xRadius)); + xml_element.setAttribute("ry", QString::number(m_yRadius)); - stylesToXml(xml_element); - return(xml_element); + stylesToXml(xml_element); } /** @@ -116,18 +118,45 @@ const QDomElement PartRectangle::toXml(QDomDocument &xml_document) const Import the properties of this rectangle from a xml element. @param qde : Xml document to use. */ -void PartRectangle::fromXml(const QDomElement &qde) +bool PartRectangle::fromXmlPriv(const QDomElement &qde) { stylesFromXml(qde); - setPos(mapFromScene(qde.attribute("x", "0").toDouble(), - qde.attribute("y", "0").toDouble())); - QRectF rect(QPointF(0,0), QSizeF(qde.attribute("width", "0").toDouble(), - qde.attribute("height", "0").toDouble())); + double x=0, y=0, w=0, h=0, rx=0, ry=0; + if (QETXML::propertyDouble(qde, "x", &x) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(qde, "y", &y) == QETXML::PropertyFlags::NoValidConversion) + return false; + + setPos(mapFromScene(x, y)); + + if (QETXML::propertyDouble(qde, "width", &w) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(qde, "height", &h) == QETXML::PropertyFlags::NoValidConversion) + return false; + + QRectF rect(QPointF(0,0), QSizeF(w, h)); setRect(rect.normalized()); - setXRadius(qde.attribute("rx", "0").toDouble()); - setYRadius(qde.attribute("ry", "0").toDouble()); + + if (QETXML::propertyDouble(qde, "rx", &rx) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(qde, "ry", &ry) == QETXML::PropertyFlags::NoValidConversion) + return false; + + setXRadius(rx); + setYRadius(ry); + + return true; +} + +bool PartRectangle::valideXml(QDomElement& element) { + // parameters have default values so no value is not a non valid xml element + if ((QETXML::propertyDouble(element, "x") & QETXML::PropertyFlags::NoValidConversion) | + (QETXML::propertyDouble(element, "y") & QETXML::PropertyFlags::NoValidConversion) | + (QETXML::propertyDouble(element, "width") & QETXML::PropertyFlags::NoValidConversion) | + (QETXML::propertyDouble(element, "height") & QETXML::PropertyFlags::NoValidConversion) | + (QETXML::propertyDouble(element, "rx") & QETXML::PropertyFlags::NoValidConversion) | + (QETXML::propertyDouble(element, "ry") & QETXML::PropertyFlags::NoValidConversion)) + return false; + return true; } /** @@ -537,9 +566,9 @@ void PartRectangle::addHandler() for (QetGraphicsHandlerItem *handler : m_handler_vector) { QColor color; - if(m_resize_mode == 1) {color = Qt::blue;} + if(m_resize_mode == 1) {color = Qt::blue;} else if (m_resize_mode == 2) {color = Qt::darkGreen;} - else {color = Qt::magenta;} + else {color = Qt::magenta;} handler->setColor(color); scene()->addItem(handler); diff --git a/sources/editor/graphicspart/partrectangle.h b/sources/editor/graphicspart/partrectangle.h index e8bbc3946..d1678a158 100644 --- a/sources/editor/graphicspart/partrectangle.h +++ b/sources/editor/graphicspart/partrectangle.h @@ -55,13 +55,16 @@ class PartRectangle : public CustomElementGraphicPart Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartRectangle. @return the QGraphicsItem type */ - int type () const override { return Type; } - void paint (QPainter *, const QStyleOptionGraphicsItem *, QWidget * = nullptr) override; + int type () const override { return Type; } + void paint (QPainter *, const QStyleOptionGraphicsItem *, QWidget * = nullptr) override; QString name () const override { return(QObject::tr("rectangle", "element part name")); } - QString xmlName () const override { return(QString("rect")); } - const QDomElement toXml (QDomDocument &) const override; - void fromXml (const QDomElement &) override; + QString xmlName () const override { return(QString("rect")); } + void toXmlPriv(QDomElement&xml_element) const override; + bool fromXmlPriv (const QDomElement &) override; + static bool valideXml(QDomElement& element); + void toSettings(QSettings &,const QString & = QString()) const override {/*TODO: implement*/} + void fromSettings(QSettings &,const QString & = QString()) override{/*TODO: implement*/} QRectF rect() const; void setRect(const QRectF &rect); @@ -90,7 +93,7 @@ class PartRectangle : public CustomElementGraphicPart void switchResizeMode(); void adjusteHandlerPos(); void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); - void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); + void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event); void sceneSelectionChanged (); diff --git a/sources/editor/graphicspart/partterminal.cpp b/sources/editor/graphicspart/partterminal.cpp index 3c5539f1a..eb83c96c3 100644 --- a/sources/editor/graphicspart/partterminal.cpp +++ b/sources/editor/graphicspart/partterminal.cpp @@ -19,6 +19,8 @@ #include "../../qetgraphicsitem/terminal.h" +#include "../../qetxml.h" + /** @brief PartTerminal::PartTerminal @param editor : @@ -29,7 +31,9 @@ PartTerminal::PartTerminal(QETElementEditor *editor, QGraphicsItem *parent) : CustomElementGraphicPart(editor, parent) { + setTagName("terminal"); d = new TerminalData(this); + d->m_name = tr("terminal"); d -> m_orientation = Qet::North; d -> m_uuid = QUuid::createUuid(); // if part is loaded this uuid will be overwritten, but being sure that terminal has a uuid updateSecondPoint(); @@ -45,10 +49,20 @@ PartTerminal::~PartTerminal() Importe les proprietes d'une borne depuis un element XML @param xml_elmt Element XML a lire */ -void PartTerminal::fromXml(const QDomElement &xml_elmt) { - d -> fromXml(xml_elmt); +bool PartTerminal::fromXmlPriv(const QDomElement &xml_elmt) { + + // update part and add uuid, which is used in the new version to connect terminals together + // if the attribute not exists, means, the element is created with an older version of qet. So use the legacy approach + // to identify terminals + QETXML::propertyUuid(xml_elmt, "uuid", &d->m_uuid); + + if (!d->fromXml(xml_elmt)) + return false; + setPos(d -> m_pos); updateSecondPoint(); + + return true; } /** @@ -56,9 +70,19 @@ void PartTerminal::fromXml(const QDomElement &xml_elmt) { @param xml_document Document XML a utiliser pour creer l'element XML @return un element XML decrivant la borne */ -const QDomElement PartTerminal::toXml(QDomDocument &xml_document) const -{ - return d -> toXml(xml_document); +void PartTerminal::toXmlPriv(QDomElement& e) const { + + e.setAttribute("uuid", d->m_uuid.toString()); + + d->m_pos = pos(); + + QDomDocument doc = e.ownerDocument(); + e.appendChild(d -> toXml(doc)); + +} + +bool PartTerminal::valideXml(QDomElement& element) { + return TerminalData::valideXml(element); } /** @@ -76,8 +100,8 @@ void PartTerminal::paint( painter -> save(); // annulation des renderhints - painter -> setRenderHint(QPainter::Antialiasing, false); - painter -> setRenderHint(QPainter::TextAntialiasing, false); + painter -> setRenderHint(QPainter::Antialiasing, false); + painter -> setRenderHint(QPainter::TextAntialiasing, false); painter -> setRenderHint(QPainter::SmoothPixmapTransform, false); QPen t; @@ -223,7 +247,7 @@ QRectF PartTerminal::sceneGeometricRect() const */ void PartTerminal::startUserTransformation(const QRectF &initial_selection_rect) { Q_UNUSED(initial_selection_rect) - saved_position_ = scenePos(); + m_saved_position = scenePos(); } /** @@ -231,6 +255,6 @@ void PartTerminal::startUserTransformation(const QRectF &initial_selection_rect) */ void PartTerminal::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) { QPointF mapped_point = mapPoints( - initial_selection_rect, new_selection_rect, QList() << saved_position_).first(); + initial_selection_rect, new_selection_rect, QList() << m_saved_position).first(); setPos(mapped_point); } diff --git a/sources/editor/graphicspart/partterminal.h b/sources/editor/graphicspart/partterminal.h index ad023f0b6..0f44579f9 100644 --- a/sources/editor/graphicspart/partterminal.h +++ b/sources/editor/graphicspart/partterminal.h @@ -56,9 +56,12 @@ class PartTerminal : public CustomElementGraphicPart */ int type() const override { return Type; } QString xmlName() const override { return(QString("terminal")); } - void fromXml(const QDomElement &) override; - const QDomElement toXml(QDomDocument &) const override; - void paint( + bool fromXmlPriv(const QDomElement &) override; + void toXmlPriv(QDomElement&xml_element) const override; + static bool valideXml(QDomElement& element); + void toSettings(QSettings &,const QString & = QString()) const override {/*TODO: implement*/} + void fromSettings(QSettings &,const QString & = QString()) override{/*TODO: implement*/} + void paint( QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override; @@ -84,9 +87,9 @@ class PartTerminal : public CustomElementGraphicPart private: void updateSecondPoint(); - TerminalData* d; // pointer to the terminal data + TerminalData* d{nullptr}; // pointer to the terminal data private: - QPointF saved_position_; + QPointF m_saved_position; }; #endif diff --git a/sources/editor/graphicspart/parttext.cpp b/sources/editor/graphicspart/parttext.cpp index bd67c6881..b52368510 100644 --- a/sources/editor/graphicspart/parttext.cpp +++ b/sources/editor/graphicspart/parttext.cpp @@ -23,6 +23,8 @@ #include "../elementscene.h" #include "../ui/texteditor.h" +#include "../../qetxml.h" + /** Constructeur @param editor L'editeur d'element concerne @@ -43,8 +45,8 @@ PartText::PartText(QETElementEditor *editor, QGraphicsItem *parent) : setAcceptHoverEvents(true); setDefaultTextColor(Qt::black); setPlainText(QObject::tr( - "T", - "default text when adding a text in the element editor")); + "T", + "default text when adding a text in the element editor")); adjustItemPosition(1); // adjust textfield position after line additions/deletions @@ -67,29 +69,49 @@ PartText::~PartText() Importe les proprietes d'un texte statique depuis un element XML @param xml_element Element XML a lire */ -void PartText::fromXml(const QDomElement &xml_element) { - bool ok; +bool PartText::fromXmlPriv(const QDomElement &xml_element) +{ + int size; + QString font; - if (xml_element.hasAttribute("size")) { - int font_size = xml_element.attribute("size").toInt(&ok); - if (!ok || font_size < 1) { - font_size = 20; + if (QETXML::propertyInteger(xml_element, "size", &size) != QETXML::PropertyFlags::NotFound) + { + if (size < 1) { + size = 20; } QFont font_ = this -> font(); - font_.setPointSize(font_size); + font_.setPointSize(size); setFont(font_); } - else if (xml_element.hasAttribute("font")) { + else if (QETXML::propertyString(xml_element, "font", &font) != QETXML::PropertyFlags::NotFound) + { QFont font_; - font_.fromString(xml_element.attribute("font")); + font_.fromString(font); setFont(font_); + } else { + return false; } - setDefaultTextColor(QColor(xml_element.attribute("color", "#000000"))); - setPlainText(xml_element.attribute("text")); - setPos(xml_element.attribute("x").toDouble(), - xml_element.attribute("y").toDouble()); - setRotation(xml_element.attribute("rotation", QString::number(0)).toDouble()); + QColor color; + QString text; + QETXML::propertyColor(xml_element, "color", &color); + setDefaultTextColor(color); + + + QETXML::propertyString(xml_element, "text", &text); + setPlainText(text); + + double x=0, y=0, rot=0; + if (QETXML::propertyDouble(xml_element, "x", &x) == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(xml_element, "y", &y) == QETXML::PropertyFlags::NoValidConversion) + return false; + setPos(x, y); + + if (QETXML::propertyDouble(xml_element, "rotation", &rot) == QETXML::PropertyFlags::NoValidConversion) + return false; + setRotation(rot); + + return true; } /** @@ -97,18 +119,38 @@ void PartText::fromXml(const QDomElement &xml_element) { @param xml_document Document XML a utiliser pour creer l'element XML @return un element XML decrivant le texte statique */ -const QDomElement PartText::toXml(QDomDocument &xml_document) const +void PartText::toXmlPriv(QDomElement& xml_element) const { - QDomElement xml_element = xml_document.createElement(xmlName()); + xml_element.setAttribute("x", QString::number(pos().x())); + xml_element.setAttribute("y", QString::number(pos().y())); + xml_element.setAttribute("text", toPlainText()); + xml_element.setAttribute("font", font().toString()); + xml_element.setAttribute("rotation", QString::number(rotation())); + xml_element.setAttribute("color", defaultTextColor().name()); +} - xml_element.setAttribute("x", QString::number(pos().x())); - xml_element.setAttribute("y", QString::number(pos().y())); - xml_element.setAttribute("text", toPlainText()); - xml_element.setAttribute("font", font().toString()); - xml_element.setAttribute("rotation", QString::number(rotation())); - xml_element.setAttribute("color", defaultTextColor().name()); +bool PartText::valideXml(QDomElement& element) { - return(xml_element); + if (QETXML::propertyInteger(element, "size") == QETXML::PropertyFlags::NotFound || + QETXML::propertyString(element, "font") == QETXML::PropertyFlags::NotFound) { + return false; + } + + if (QETXML::propertyString(element, "color") == QETXML::PropertyFlags::NoValidConversion) + return false; + + + if (QETXML::propertyString(element, "text")) + return false; + + if (QETXML::propertyDouble(element, "x") == QETXML::PropertyFlags::NoValidConversion || + QETXML::propertyDouble(element, "y") == QETXML::PropertyFlags::NoValidConversion) + return false; + + if (QETXML::propertyDouble(element, "rotation", 0) == QETXML::PropertyFlags::NoValidConversion) + return false; + + return true; } /** diff --git a/sources/editor/graphicspart/parttext.h b/sources/editor/graphicspart/parttext.h index 32efadce9..3cc9c5bbf 100644 --- a/sources/editor/graphicspart/parttext.h +++ b/sources/editor/graphicspart/parttext.h @@ -59,8 +59,11 @@ class PartText : public QGraphicsTextItem, public CustomElementPart { int type() const override { return Type; } QString name() const override { return(QObject::tr("texte", "element part name")); } QString xmlName() const override { return(QString("text")); } - void fromXml(const QDomElement &) override; - const QDomElement toXml(QDomDocument &) const override; + bool fromXmlPriv(const QDomElement &) override; + static bool valideXml(QDomElement& element); + void toSettings(QSettings &,const QString & = QString()) const override {/*TODO: implement*/} + void fromSettings(QSettings &,const QString & = QString()) override{/*TODO: implement*/} + void toXmlPriv(QDomElement&xml_element) const override; void setRotation(qreal angle) {(QGraphicsObject::setRotation(QET::correctAngle(angle)));} bool isUseless() const override; QRectF sceneGeometricRect() const override; diff --git a/sources/editor/styleeditor.cpp b/sources/editor/styleeditor.cpp index d9791810d..fbea26dab 100644 --- a/sources/editor/styleeditor.cpp +++ b/sources/editor/styleeditor.cpp @@ -440,10 +440,10 @@ void StyleEditor::updatePartFilling() } /** - @brief StyleEditor::updateForm + @brief StyleEditor::updateFormPriv Update the edition form according to the value of edited part(s) */ -void StyleEditor::updateForm() +void StyleEditor::updateFormPriv() { if (!part && m_part_list.isEmpty()) return; activeConnections(false); diff --git a/sources/editor/styleeditor.h b/sources/editor/styleeditor.h index 20a63fb3b..775a3ed16 100644 --- a/sources/editor/styleeditor.h +++ b/sources/editor/styleeditor.h @@ -60,7 +60,7 @@ class StyleEditor : public ElementItemEditor static bool isStyleEditable (QList cep_list); public slots: - void updateForm() override; + void updateFormPriv() override; void updatePartAntialiasing(); void updatePartColor(); void updatePartLineStyle(); diff --git a/sources/editor/ui/dynamictextfieldeditor.cpp b/sources/editor/ui/dynamictextfieldeditor.cpp index e9135d52e..6c2876d06 100644 --- a/sources/editor/ui/dynamictextfieldeditor.cpp +++ b/sources/editor/ui/dynamictextfieldeditor.cpp @@ -51,8 +51,8 @@ DynamicTextFieldEditor::DynamicTextFieldEditor(QETElementEditor *editor, DynamicTextFieldEditor::~DynamicTextFieldEditor() { delete ui; - if(!m_connection_list.isEmpty()) { - for(const QMetaObject::Connection& con : m_connection_list) { + if(!m_change_connections.isEmpty()) { + for(const QMetaObject::Connection& con : m_change_connections) { disconnect(con); } } @@ -130,7 +130,7 @@ QList DynamicTextFieldEditor::currentParts() const return parts; } -void DynamicTextFieldEditor::updateForm() +void DynamicTextFieldEditor::updateFormPriv() { if(m_text_field) { ui -> m_x_sb -> setValue(m_text_field.data() -> x()); @@ -182,38 +182,38 @@ void DynamicTextFieldEditor::setupWidget() void DynamicTextFieldEditor::setUpConnections() { - assert(m_connection_list.isEmpty()); + assert(m_change_connections.isEmpty()); //Setup the connection - m_connection_list << connect(m_text_field.data(), &PartDynamicTextField::colorChanged, + m_change_connections << connect(m_text_field.data(), &PartDynamicTextField::colorChanged, [this](){this -> updateForm();}); - m_connection_list << connect(m_text_field.data(), &PartDynamicTextField::fontChanged, + m_change_connections << connect(m_text_field.data(), &PartDynamicTextField::fontChanged, [this](){this -> updateForm();}); - m_connection_list << connect(m_text_field.data(), &PartDynamicTextField::taggChanged, + m_change_connections << connect(m_text_field.data(), &PartDynamicTextField::taggChanged, [this](){this -> updateForm();}); - m_connection_list << connect(m_text_field.data(), &PartDynamicTextField::textFromChanged, + m_change_connections << connect(m_text_field.data(), &PartDynamicTextField::textFromChanged, [this](){this -> updateForm();}); - m_connection_list << connect(m_text_field.data(), &PartDynamicTextField::textChanged, + m_change_connections << connect(m_text_field.data(), &PartDynamicTextField::textChanged, [this](){this -> updateForm();}); - m_connection_list << connect(m_text_field.data(), &PartDynamicTextField::infoNameChanged, + m_change_connections << connect(m_text_field.data(), &PartDynamicTextField::infoNameChanged, [this](){this -> updateForm();}); - m_connection_list << connect(m_text_field.data(), &PartDynamicTextField::rotationChanged, + m_change_connections << connect(m_text_field.data(), &PartDynamicTextField::rotationChanged, [this](){this -> updateForm();}); - m_connection_list << connect(m_text_field.data(), &PartDynamicTextField::frameChanged, + m_change_connections << connect(m_text_field.data(), &PartDynamicTextField::frameChanged, [this](){this -> updateForm();}); - m_connection_list << connect(m_text_field.data(), &PartDynamicTextField::textWidthChanged, + m_change_connections << connect(m_text_field.data(), &PartDynamicTextField::textWidthChanged, [this](){this -> updateForm();}); - m_connection_list << connect(m_text_field.data(), &PartDynamicTextField::compositeTextChanged, + m_change_connections << connect(m_text_field.data(), &PartDynamicTextField::compositeTextChanged, [this](){this -> updateForm();}); } void DynamicTextFieldEditor::disconnectConnections() { //Remove previous connection - if(!m_connection_list.isEmpty()) - for(const QMetaObject::Connection& con : m_connection_list) { + if(!m_change_connections.isEmpty()) + for(const QMetaObject::Connection& con : m_change_connections) { disconnect(con); } - m_connection_list.clear(); + m_change_connections.clear(); } /** diff --git a/sources/editor/ui/dynamictextfieldeditor.h b/sources/editor/ui/dynamictextfieldeditor.h index e84c20228..3c4718263 100644 --- a/sources/editor/ui/dynamictextfieldeditor.h +++ b/sources/editor/ui/dynamictextfieldeditor.h @@ -45,7 +45,7 @@ class DynamicTextFieldEditor : public ElementItemEditor { bool setParts(QList ) override; CustomElementPart *currentPart() const override; QList currentParts() const override; - void updateForm() override; + void updateFormPriv() override; private: void setupWidget(); @@ -73,7 +73,6 @@ class DynamicTextFieldEditor : public ElementItemEditor { Ui::DynamicTextFieldEditor *ui; QPointer m_text_field; QList m_parts; - QList m_connection_list; #ifdef BUILD_WITHOUT_KF5 #else diff --git a/sources/editor/ui/ellipseeditor.cpp b/sources/editor/ui/ellipseeditor.cpp index d0b7b7511..57322571e 100644 --- a/sources/editor/ui/ellipseeditor.cpp +++ b/sources/editor/ui/ellipseeditor.cpp @@ -110,9 +110,9 @@ QList EllipseEditor::currentParts() const { } /** - * @brief EllipseEditor::updateForm + * @brief EllipseEditor::updateFormPriv */ -void EllipseEditor::updateForm() +void EllipseEditor::updateFormPriv() { if (!m_part) { return; diff --git a/sources/editor/ui/ellipseeditor.h b/sources/editor/ui/ellipseeditor.h index 47a24764e..df1a8d56e 100644 --- a/sources/editor/ui/ellipseeditor.h +++ b/sources/editor/ui/ellipseeditor.h @@ -43,7 +43,7 @@ class EllipseEditor : public ElementItemEditor bool setParts(QList parts) override; CustomElementPart *currentPart() const override; QList currentParts() const override; - void updateForm() override; + void updateFormPriv() override; private slots: void on_m_x_sb_editingFinished(); @@ -59,8 +59,7 @@ class EllipseEditor : public ElementItemEditor private: Ui::EllipseEditor *ui; PartEllipse *m_part = nullptr; - StyleEditor *m_style = nullptr; - QList m_change_connections; + StyleEditor *m_style = nullptr; }; diff --git a/sources/editor/ui/lineeditor.cpp b/sources/editor/ui/lineeditor.cpp index dd31c310e..4ebd89445 100644 --- a/sources/editor/ui/lineeditor.cpp +++ b/sources/editor/ui/lineeditor.cpp @@ -176,10 +176,10 @@ QList LineEditor::currentParts() const { } /** - @brief LineEditor::updateForm + @brief LineEditor::updateFormPriv Reimplemented from ElementItemEditor */ -void LineEditor::updateForm() +void LineEditor::updateFormPriv() { if (!m_part) { return; diff --git a/sources/editor/ui/lineeditor.h b/sources/editor/ui/lineeditor.h index 8e1496893..0807dc150 100644 --- a/sources/editor/ui/lineeditor.h +++ b/sources/editor/ui/lineeditor.h @@ -43,7 +43,7 @@ class LineEditor : public ElementItemEditor bool setParts(QList parts) override; CustomElementPart *currentPart() const override; QList currentParts() const override; - void updateForm() override; + void updateFormPriv() override; private: void setUpChangeConnections(); @@ -59,8 +59,7 @@ class LineEditor : public ElementItemEditor private: PartLine *m_part = nullptr; Ui::LineEditor *ui; - StyleEditor *m_style = nullptr; - QList m_change_connections; + StyleEditor *m_style = nullptr; bool m_locked = false; }; diff --git a/sources/editor/ui/polygoneditor.cpp b/sources/editor/ui/polygoneditor.cpp index e2c8b1720..5b5392619 100644 --- a/sources/editor/ui/polygoneditor.cpp +++ b/sources/editor/ui/polygoneditor.cpp @@ -130,10 +130,10 @@ QList PolygonEditor::currentParts() const } /** - @brief PolygonEditor::updateForm + @brief PolygonEditor::updateFormPriv Update the widget */ -void PolygonEditor::updateForm() +void PolygonEditor::updateFormPriv() { if (!m_part) { return; diff --git a/sources/editor/ui/polygoneditor.h b/sources/editor/ui/polygoneditor.h index c13dad752..3712c4c00 100644 --- a/sources/editor/ui/polygoneditor.h +++ b/sources/editor/ui/polygoneditor.h @@ -39,7 +39,7 @@ class PolygonEditor : public ElementItemEditor bool setPart(CustomElementPart *part) override; CustomElementPart *currentPart() const override; QList currentParts() const override; - void updateForm() override; + void updateFormPriv() override; QVector pointsFromTree(); bool eventFilter(QObject *watched, QEvent *event) override; @@ -63,7 +63,6 @@ class PolygonEditor : public ElementItemEditor Ui::PolygonEditor *ui; StyleEditor *m_style = nullptr; PartPolygon *m_part = nullptr; - QList m_change_connections; }; #endif // POLYGONEDITOR_H diff --git a/sources/editor/ui/rectangleeditor.cpp b/sources/editor/ui/rectangleeditor.cpp index 49a49ab99..8fc505dcc 100644 --- a/sources/editor/ui/rectangleeditor.cpp +++ b/sources/editor/ui/rectangleeditor.cpp @@ -136,7 +136,7 @@ QPointF RectangleEditor::editedTopLeft() const /** @brief RectangleEditor::updateForm */ -void RectangleEditor::updateForm() +void RectangleEditor::updateFormPriv() { if (!m_part) { return; diff --git a/sources/editor/ui/rectangleeditor.h b/sources/editor/ui/rectangleeditor.h index f074a2124..01a375341 100644 --- a/sources/editor/ui/rectangleeditor.h +++ b/sources/editor/ui/rectangleeditor.h @@ -48,7 +48,7 @@ class RectangleEditor : public ElementItemEditor QPointF editedTopLeft () const; public slots: - void updateForm() override; + void updateFormPriv() override; private: void editingFinished(); void activeConnections(bool active); @@ -70,7 +70,6 @@ class RectangleEditor : public ElementItemEditor StyleEditor *m_style; PartRectangle *m_part; Ui::RectangleEditor *ui; - QList m_change_connections; }; #endif // RECTANGLEEDITOR_H diff --git a/sources/editor/ui/terminaleditor.cpp b/sources/editor/ui/terminaleditor.cpp index a3edf8e54..01fbc9181 100644 --- a/sources/editor/ui/terminaleditor.cpp +++ b/sources/editor/ui/terminaleditor.cpp @@ -46,11 +46,11 @@ TerminalEditor::~TerminalEditor() } /** - * @brief TerminalEditor::updateForm + * @brief TerminalEditor::updateFormPriv * Reimplemented from ElementItemEditor * Update the content of this widget */ -void TerminalEditor::updateForm() +void TerminalEditor::updateFormPriv() { if (!m_part) { return; diff --git a/sources/editor/ui/terminaleditor.h b/sources/editor/ui/terminaleditor.h index 2a708add9..33baae9c7 100644 --- a/sources/editor/ui/terminaleditor.h +++ b/sources/editor/ui/terminaleditor.h @@ -39,7 +39,7 @@ class TerminalEditor : public ElementItemEditor TerminalEditor(QETElementEditor *editor, QWidget *parent = nullptr); ~TerminalEditor() override; - void updateForm() override; + void updateFormPriv() override; bool setPart(CustomElementPart *new_part) override; CustomElementPart *currentPart() const override; QList currentParts() const override {return QList();} @@ -55,8 +55,7 @@ class TerminalEditor : public ElementItemEditor private: Ui::TerminalEditor *ui; - QVector m_editor_connections, - m_change_connections; + QVector m_editor_connections; PartTerminal *m_part = nullptr; bool m_locked = false; }; diff --git a/sources/editor/ui/texteditor.cpp b/sources/editor/ui/texteditor.cpp index 512a5614b..a9a95d2ad 100644 --- a/sources/editor/ui/texteditor.cpp +++ b/sources/editor/ui/texteditor.cpp @@ -48,7 +48,7 @@ TextEditor::~TextEditor() {} @brief TextEditor::updateForm Update the gui */ -void TextEditor::updateForm() +void TextEditor::updateFormPriv() { if (m_text.isNull()) { return; diff --git a/sources/editor/ui/texteditor.h b/sources/editor/ui/texteditor.h index 0e7cfd32c..4ede518e1 100644 --- a/sources/editor/ui/texteditor.h +++ b/sources/editor/ui/texteditor.h @@ -38,7 +38,7 @@ class TextEditor : public ElementItemEditor { explicit TextEditor(QETElementEditor *editor, PartText *text = nullptr, QWidget *parent = nullptr); ~TextEditor() override; - void updateForm() override; + void updateFormPriv() override; bool setPart(CustomElementPart *part) override; bool setParts(QList ) override; CustomElementPart *currentPart() const override; diff --git a/sources/elementtextpattern.cpp b/sources/elementtextpattern.cpp index 721cc13a5..c8c4efe04 100644 --- a/sources/elementtextpattern.cpp +++ b/sources/elementtextpattern.cpp @@ -109,8 +109,7 @@ QDomDocument ExportElementTextPattern::xmlConf() const root.setAttribute("name", m_name); doc.appendChild(root); - QHash H; - QDomElement elmt = m_element->toXml(doc, H); + QDomElement elmt = m_element->toXml(doc); QDomElement texts = elmt.firstChildElement("dynamic_texts"); QDomElement groups = elmt.firstChildElement("texts_groups"); diff --git a/sources/machine_info.cpp b/sources/machine_info.cpp index 2c6898ce2..b33f88c8d 100644 --- a/sources/machine_info.cpp +++ b/sources/machine_info.cpp @@ -147,7 +147,15 @@ void Machine_info::send_info_to_debug() + " x " + QString::number(pc.screen.height[ii]) + " )"; - } + } +} + +/** + @brief Machine_info::~Machine_info + destructor +*/ +Machine_info::~Machine_info() +{ } /** diff --git a/sources/machine_info.h b/sources/machine_info.h index a52f458a7..7909a6b61 100644 --- a/sources/machine_info.h +++ b/sources/machine_info.h @@ -34,6 +34,7 @@ public: int32_t i_max_screen_height(); QString compilation_info(); void send_info_to_debug(); + ~Machine_info(); signals: diff --git a/sources/properties/elementdata.cpp b/sources/properties/elementdata.cpp index 9cab02db4..abf7e1c3b 100644 --- a/sources/properties/elementdata.cpp +++ b/sources/properties/elementdata.cpp @@ -19,19 +19,18 @@ #include "../qetxml.h" #include -void ElementData::toSettings(QSettings &settings, const QString prefix) const { +void ElementData::toSettings(QSettings &settings, const QString& prefix) const { Q_UNUSED(settings) Q_UNUSED(prefix) } -void ElementData::fromSettings(const QSettings &settings, const QString prefix) { +void ElementData::fromSettings(QSettings &settings, const QString& prefix) { Q_UNUSED(settings) Q_UNUSED(prefix) } -QDomElement ElementData::toXml(QDomDocument &xml_element) const { - Q_UNUSED(xml_element) - return QDomElement(); +void ElementData::toXmlPriv(QDomElement& e) const { + Q_UNUSED(e) } /** @@ -42,7 +41,7 @@ QDomElement ElementData::toXml(QDomDocument &xml_element) const { * @param xml_element : tagName must be 'definition' * @return true is successfuly loaded */ -bool ElementData::fromXml(const QDomElement &xml_element) +bool ElementData::fromXmlPriv(const QDomElement &xml_element) { if(xml_element.tagName() != "definition" || xml_element.attribute("type") != "element") { diff --git a/sources/properties/elementdata.h b/sources/properties/elementdata.h index e7e3d740d..2393445d7 100644 --- a/sources/properties/elementdata.h +++ b/sources/properties/elementdata.h @@ -18,7 +18,7 @@ #ifndef ELEMENTDATA_H #define ELEMENTDATA_H -#include "propertiesinterface.h" +#include "../properties/propertiesinterface.h" #include "../diagramcontext.h" #include "../NameList/nameslist.h" @@ -85,10 +85,10 @@ class ElementData : public PropertiesInterface ElementData() {} ~ElementData() override {} - void toSettings(QSettings &settings, const QString prefix = QString()) const override; - void fromSettings(const QSettings &settings, const QString prefix = QString()) override; - QDomElement toXml(QDomDocument &xml_element) const override; - bool fromXml(const QDomElement &xml_element) override; + void toSettings(QSettings &settings, const QString& prefix = QString()) const override; + void fromSettings(QSettings &settings, const QString& prefix = QString()) override; + void toXmlPriv(QDomElement &) const override; + bool fromXmlPriv(const QDomElement &xml_element) override; QDomElement kindInfoToXml(QDomDocument &document); bool operator==(const ElementData &data) const; diff --git a/sources/properties/propertiesinterface.cpp b/sources/properties/propertiesinterface.cpp index 3e5fb1753..1899595b2 100644 --- a/sources/properties/propertiesinterface.cpp +++ b/sources/properties/propertiesinterface.cpp @@ -16,17 +16,230 @@ along with QElectroTech. If not, see . */ #include "propertiesinterface.h" +#include +#include "../qetxml.h" + +/*! + * Available property types + */ +namespace { + + const QString userPropertiesS = "userProperties"; +} /** @brief PropertiesInterface::PropertiesInterface */ -PropertiesInterface::PropertiesInterface() +PropertiesInterface::PropertiesInterface(const QString &tagname): + mTagName(tagname) { } + /** @brief PropertiesInterface::~PropertiesInterface */ PropertiesInterface::~PropertiesInterface() { - +} + +void PropertiesInterface::setTagName(const QString& tagname) +{ + mTagName = tagname; +} + +QString PropertiesInterface::tagName() const +{ + return mTagName; +} + +QDomElement PropertiesInterface::toXml (QDomDocument &xml_document) const +{ + QDomElement element = xml_document.createElement(mTagName); + toXmlPriv(element); + propertiesToXml(element); + + return element; +} + +bool PropertiesInterface::fromXml (const QDomElement &xml_element) +{ + if (!fromXmlPriv(xml_element)) + return false; + + if (!propertiesFromXml(xml_element)) + return false; + + return true; +} + +bool PropertiesInterface::valideXml(QDomElement& element) { + qDebug(QString("ValideXml() is not implemented. File: %1, Line: %2").arg(__FILE__).arg(__LINE__).toStdString().data()); + return false; +} + +/** + Permet de convertir une chaine de caracteres ("n", "s", "e" ou "w") + en orientation. Si la chaine fait plusieurs caracteres, seul le + premier est pris en compte. En cas d'incoherence, Qet::North est + retourne. + @param s Chaine de caractere cense representer une orientation + @return l'orientation designee par la chaine de caractere +*/ +Qet::Orientation PropertiesInterface::orientationFromString(const QString &s) { + QChar c = s[0]; + // in some cases/ old projects? (affuteuse_250h.qet) numbers instead of characters are + // used for the orientation + if (c == 'e' || c == '1') return(Qet::East); + else if (c == 's' || c == '2') return(Qet::South); + else if (c == 'w' || c == '3') return (Qet::West); + else return(Qet::North); // c == '0' +} + +/** + @param o une orientation + @return une chaine de caractere representant l'orientation +*/ +QString PropertiesInterface::orientationToString(Qet::Orientation o) { + QString ret; + switch(o) { + case Qet::North: ret = "n"; break; + case Qet::East : ret = "e"; break; + case Qet::South: ret = "s"; break; + case Qet::West : ret = "w"; break; + } + return(ret); +} + +void PropertiesInterface::deleteUserProperties() +{ + properties.clear(); +} + +int PropertiesInterface::userPropertiesCount() const +{ + return properties.count(); +} + +void PropertiesInterface::setUserProperty(const QString& key, const QVariant& value) +{ + properties[key] = value; +} + +bool PropertiesInterface::existUserProperty(const QString& key) const +{ + return properties.contains(key); +} + +QVariant PropertiesInterface::userPropertyValue(const QString& key) +{ + if (!existUserProperty(key)) + return QVariant(); + + return properties[key]; +} + +void PropertiesInterface::propertiesToXml(QDomElement& e) const +{ + if (properties.count() == 0) + return; + + QDomDocument doc = e.ownerDocument(); + auto up = doc.createElement(userPropertiesS); + for (auto i = properties.begin(); i != properties.end(); ++i) + { + auto type = i.value().type(); + switch(type) { + case QVariant::Type::String: + up.appendChild(QETXML::createXmlProperty(i.key(), i.value().toString())); break; + case QVariant::Type::Int: + up.appendChild(QETXML::createXmlProperty(i.key(), i.value().toInt())); break; + case QVariant::Type::Double: + up.appendChild(QETXML::createXmlProperty(i.key(), i.value().toDouble())); break; + case QVariant::Type::Bool: + up.appendChild(QETXML::createXmlProperty(i.key(), i.value().toBool())); break; + case QVariant::Type::Color: + up.appendChild(QETXML::createXmlProperty(i.key(), QColor(i.value().value()))); break; + default: + break; + } + } + e.appendChild(up); +} + +/*! + * \brief PropertiesInterface::propertiesFromXml + * Read all user properties from the DomElement& e + * \param e + * \return + */ +bool PropertiesInterface::propertiesFromXml(const QDomElement& e) +{ + QDomNodeList l = e.childNodes(); + for (int i=0; i < l.count(); i++) + { + QDomElement userProperties = l.at(i).toElement(); + if (userProperties.tagName() != userPropertiesS) + continue; + + QDomElement userProperty; + for (int up_index = 0; up_index < userProperties.childNodes().length(); up_index++) + { + userProperty = userProperties.childNodes().at(up_index).toElement(); + + QString name = userProperty.attribute("name"); + QString type = userProperty.attribute("type"); + QString value = userProperty.attribute("value"); + + if (type == QETXML::integerS) + { + int i; + if (QETXML::propertyInteger(value, &i) == QETXML::PropertyFlags::Success) + properties[name] = QVariant(i); + else + return false; + } + else if (type == QETXML::doubleS) + { + double d; + if (QETXML::propertyDouble(value, &d) == QETXML::PropertyFlags::Success) + properties[name] = QVariant(d); + else + return false; + } + else if (type == QETXML::boolS) + { + bool b; + if (QETXML::propertyBool(value, &b) == QETXML::PropertyFlags::Success) + properties[name] = QVariant(b); + else + return false; + } + else if (type == QETXML::uuidS) + { + QUuid u; + if (QETXML::propertyUuid(value, &u) == QETXML::PropertyFlags::Success) + properties[name] = QVariant(u); + else + return false; + } + else if (type == QETXML::colorS) + { + QColor c; + if (QETXML::propertyColor(value, &c) == QETXML::PropertyFlags::Success) + properties[name] = QVariant(c); + else + return false; + } + else if (type == QETXML::stringS) + { + properties[name] = QVariant(value); + } + else + { + qDebug() << "Not a valid property type!"; + } + } + } + + return true; } diff --git a/sources/properties/propertiesinterface.h b/sources/properties/propertiesinterface.h index 51fa348b4..0d2b6d119 100644 --- a/sources/properties/propertiesinterface.h +++ b/sources/properties/propertiesinterface.h @@ -20,7 +20,11 @@ #include #include +#include #include +#include +#include "sources/qet.h" +#include /** @brief The PropertiesInterface class @@ -30,7 +34,7 @@ class PropertiesInterface { public: - PropertiesInterface(); + PropertiesInterface(const QString& tagname = "Properties"); virtual ~PropertiesInterface(); /** @brief toSettings @@ -39,8 +43,8 @@ class PropertiesInterface befor the name of each paramètre @param QString */ - virtual void toSettings (QSettings &settings, - const QString = QString()) const =0; + virtual void toSettings(QSettings &, + const QString & = QString()) const =0; /** @brief fromSettings load properties to setting file. @@ -48,22 +52,98 @@ class PropertiesInterface befor the name of each paramètre @param QString */ - virtual void fromSettings (const QSettings &settings, - const QString = QString()) =0; + virtual void fromSettings(QSettings &, + const QString & = QString()) = 0; /** @brief toXml Save properties to xml element @param xml_document @return QDomElement */ - virtual QDomElement toXml (QDomDocument &xml_document) const =0; + virtual QDomElement toXml (QDomDocument &xml_document) const; /** @brief fromXml load properties to xml element @param xml_element @return true / false */ - virtual bool fromXml (const QDomElement &xml_element) =0; + virtual bool fromXml (const QDomElement &xml_element); + + /*! + * \brief deleteUserProperties + * Delete all userproperties + */ + void deleteUserProperties(); + + /*! + * \brief userPropertiesCount + * Returns the number of user properties + * \return + */ + int userPropertiesCount() const; + + /*! + * \brief setUserProperty + * Adds a new property if \p key does not exist in the \p properties member, + * otherwise overwrite the value + * \param key + * \param value + */ + void setUserProperty(const QString& key, const QVariant& value); + + /*! + * \brief existUserProperty + * Checks if a user property with key \p key is available or not + * \param key + * \return + */ + bool existUserProperty(const QString& key) const; + + /*! + * \brief userProperty + * Returns the value of a user property with key \p key + * If \p key is not found, an invalid QVariant is returned. + * Use QVariant::type() to get the type of the vale + * \param key + * \return + */ + QVariant userPropertyValue(const QString& key); + + + static bool valideXml(QDomElement& element); + + void setTagName(const QString& tagname); + QString tagName() const; + + /** + Permet de convertir une chaine de caracteres ("n", "s", "e" ou "w") + en orientation. Si la chaine fait plusieurs caracteres, seul le + premier est pris en compte. En cas d'incoherence, Qet::North est + retourne. + @param s Chaine de caractere cense representer une orientation + @return l'orientation designee par la chaine de caractere + */ + static Qet::Orientation orientationFromString(const QString &s); + + /** + @param o une orientation + @return une chaine de caractere representant l'orientation + */ + static QString orientationToString(Qet::Orientation o); + +private: + virtual void toXmlPriv (QDomElement &e) const =0; + virtual bool fromXmlPriv (const QDomElement &e) =0; + /*! + * \brief PropertiesInterface::propertiesToXml + * Write all user properties to the DomElement \p e + * \param e + */ + void propertiesToXml(QDomElement& e) const; + bool propertiesFromXml (const QDomElement &e); + + QHash properties; + QString mTagName{""}; }; #endif // PROPERTIESINTERFACE_H diff --git a/sources/properties/terminaldata.cpp b/sources/properties/terminaldata.cpp index 791cec88b..dd3f094bd 100644 --- a/sources/properties/terminaldata.cpp +++ b/sources/properties/terminaldata.cpp @@ -20,14 +20,16 @@ #include #include +#include "../qetxml.h" + TerminalData::TerminalData(): - PropertiesInterface() + PropertiesInterface("terminaldata") { init(); } TerminalData::TerminalData(QGraphicsObject *parent): - PropertiesInterface(), + PropertiesInterface("terminaldata"), q(parent) { init(); @@ -59,7 +61,7 @@ void TerminalData::setParent(QGraphicsObject* parent) @param settings UNUSED @param prefix UNUSED */ -void TerminalData::toSettings(QSettings &settings, const QString prefix) const +void TerminalData::toSettings(QSettings &settings, const QString &prefix) const { Q_UNUSED(settings) @@ -74,44 +76,39 @@ void TerminalData::toSettings(QSettings &settings, const QString prefix) const @param settings UNUSED @param prefix UNUSED */ -void TerminalData::fromSettings(const QSettings &settings, const QString prefix) +void TerminalData::fromSettings(QSettings &settings, const QString& prefix) { Q_UNUSED(settings) Q_UNUSED(prefix) } /** - @brief TerminalData::toXml + @brief TerminalData::toXmlPriv Save properties to xml element write the name, number, position and orientation of the terminal to xml_element @note This method is only called from the PartTerminal and should never called from the Terminal class - @param xml_document - @return xml_element : DomElement with + @param e: element to store the properties the name, number, position and orientation of the terminal */ -QDomElement TerminalData::toXml(QDomDocument &xml_document) const +void TerminalData::toXmlPriv(QDomElement& xml_element) const { - QDomElement xml_element = xml_document.createElement("terminal"); + xml_element.setAttribute("x", QString("%1").arg(q->scenePos().x())); + xml_element.setAttribute("y", QString("%1").arg(q->scenePos().y())); - xml_element.setAttribute("x", QString("%1").arg(q->scenePos().x())); - xml_element.setAttribute("y", QString("%1").arg(q->scenePos().y())); + xml_element.setAttribute("uuid", m_uuid.toString()); + xml_element.setAttribute("name", m_name); - xml_element.setAttribute("uuid", m_uuid.toString()); - xml_element.setAttribute("name", m_name); + xml_element.setAttribute("orientation", + orientationToString(m_orientation)); - xml_element.setAttribute("orientation", - Qet::orientationToString(m_orientation)); - - xml_element.setAttribute("type", typeToString(m_type)); - - return(xml_element); + xml_element.setAttribute("type", typeToString(m_type)); } -/** - @brief TerminalData::fromXml +/* + @brief TerminalData::fromXmlPriv load properties to xml element @note This method is only called from the PartTerminal @@ -119,41 +116,67 @@ QDomElement TerminalData::toXml(QDomDocument &xml_document) const @param xml_element @return true if succeeded / false if the attribute is not real */ -bool TerminalData::fromXml (const QDomElement &xml_element) +bool TerminalData::fromXmlPriv(const QDomElement &xml_element) { qreal term_x = 0.0; qreal term_y = 0.0; // reads the position of the terminal // lit la position de la borne - if (!QET::attributeIsAReal(xml_element, "x", &term_x)) + + if (QETXML::propertyDouble(xml_element, "x", &term_x)) return false; - if (!QET::attributeIsAReal(xml_element, "y", &term_y)) + if (QETXML::propertyDouble(xml_element, "y", &term_y)) return false; m_pos = QPointF(term_x, term_y); - //emit posFromXML(QPointF(term_x, term_y)); +// emit posFromXML(QPointF(term_x, term_y)); - QString uuid = xml_element.attribute("uuid"); - // update part and add uuid, which is used in the new version - // to connect terminals together + // do not write uuid from this class, because only PartTerminal::fromXml need + // to write it to xml file. Terminal::fromXml does not need. // if the attribute not exists, means, the element is created with an // older version of qet. So use the legacy approach - // to identify terminals - if (!uuid.isEmpty()) - m_uuid = QUuid(uuid); - m_name = xml_element.attribute("name"); + + //if (QETXML::propertyString(xml_element, "name", &m_name)) + // return false; + QETXML::propertyString(xml_element, "name", &m_name); // some parts do not have a name. Example: affuteuse_250h.qet, Terminal at x="0" y="-20" + + QString o; + if (QETXML::propertyString(xml_element, "orientation", &o)) + return false; // read the orientation of the terminal // lit l'orientation de la borne - m_orientation = Qet::orientationFromString( - xml_element.attribute("orientation")); + m_orientation = orientationFromString(o); + + QString type; + if (QETXML::propertyString(xml_element, "type", &type) == QETXML::PropertyFlags::Success) + m_type = typeFromString(type); - m_type = typeFromString(xml_element.attribute("type")); + return true; +} +bool TerminalData::valideXml(const QDomElement& xml_element) { + if (QETXML::propertyDouble(xml_element, "x")) + return false; + + // Old projects do not have this property. +// if (QETXML::propertyString(xml_element, "type")) +// return false; + + + // legacy elements do not have an uuid +// if (QETXML::propertyUuid(xml_element, "uuid")) +// return false; + + //if (QETXML::propertyString(xml_element, "name")) // some parts do not have a name. Example: affuteuse_250h.qet, Terminal at x="0" y="-20" + // return false; + + if (QETXML::propertyString(xml_element, "orientation")) + return false; return true; } diff --git a/sources/properties/terminaldata.h b/sources/properties/terminaldata.h index 4f8c8c30a..6690c9c78 100644 --- a/sources/properties/terminaldata.h +++ b/sources/properties/terminaldata.h @@ -19,7 +19,7 @@ #define TERMINALDATA_H #include "../qet.h" -#include "propertiesinterface.h" +#include "../properties/propertiesinterface.h" #include #include @@ -53,11 +53,13 @@ class TerminalData : public PropertiesInterface void setParent(QGraphicsObject* parent); void toSettings(QSettings &settings, - const QString prefix = QString()) const override; - void fromSettings(const QSettings &settings, - const QString prefix = QString()) override; - QDomElement toXml(QDomDocument &xml_element) const override; - bool fromXml(const QDomElement &xml_element) override; + const QString& prefix = QString()) const override; + void fromSettings(QSettings &settings, + const QString& = QString()) override; + void toXmlPriv(QDomElement &xml_element) const override; + bool fromXmlPriv(const QDomElement &xml_element) override; + + static bool valideXml(const QDomElement &xml_element); static QString typeToString(TerminalData::Type type); static TerminalData::Type typeFromString(const QString &string); @@ -69,13 +71,13 @@ class TerminalData : public PropertiesInterface @brief m_orientation Orientation of the terminal */ - Qet::Orientation m_orientation; + Qet::Orientation m_orientation{Qet::Orientation::North}; /** - @brief second_point + @brief m_second_point Position of the second point of the terminal in scene coordinates */ - QPointF m_second_point; + QPointF m_second_point{0,0}; /** @brief m_uuid Uuid of the terminal. @@ -90,7 +92,7 @@ class TerminalData : public PropertiesInterface valid. So if in the loaded document a uuid exists, use this one and don't create a new one. */ - QUuid m_uuid; + QUuid m_uuid; // default is an invalid uuid. /** @brief m_name Name of the element. @@ -108,10 +110,8 @@ class TerminalData : public PropertiesInterface It is used to store the initial position so that PartTerminal and Terminal have access to it. */ - QPointF m_pos; - + QPointF m_pos{0,0}; TerminalData::Type m_type = TerminalData::Generic; - private: QGraphicsObject* q{nullptr}; }; diff --git a/sources/properties/xrefproperties.cpp b/sources/properties/xrefproperties.cpp index 06c513c19..0e872c4c8 100644 --- a/sources/properties/xrefproperties.cpp +++ b/sources/properties/xrefproperties.cpp @@ -22,20 +22,15 @@ #include #include +#include "../qetxml.h" + /** @brief XRefProperties::XRefProperties Default Constructor */ XRefProperties::XRefProperties() { - m_show_power_ctc = true; - m_display = Cross; - m_snap_to = Bottom; - m_prefix_keys << "power" << "delay" << "switch"; - m_master_label = "%f-%l%c"; - m_slave_label = "(%f-%l%c)"; - m_offset = 0; - m_xref_pos = Qt::AlignBottom; + setTagName("xref"); } /** @@ -45,7 +40,7 @@ XRefProperties::XRefProperties() @param prefix: prefix before properties name */ void XRefProperties::toSettings(QSettings &settings, - const QString prefix) const + const QString &prefix) const { settings.setValue(prefix + "showpowerctc", m_show_power_ctc); QString display = m_display == Cross? "cross" : "contacts"; @@ -74,8 +69,8 @@ void XRefProperties::toSettings(QSettings &settings, @param settings: QSettings to use @param prefix: prefix before properties name */ -void XRefProperties::fromSettings(const QSettings &settings, - const QString prefix) +void XRefProperties::fromSettings(QSettings &settings, + const QString &prefix) { m_show_power_ctc = settings.value(prefix + "showpowerctc", true).toBool(); QString display = settings.value(prefix + "displayhas", "cross").toString(); @@ -100,62 +95,66 @@ void XRefProperties::fromSettings(const QSettings &settings, @param xml_document : QDomElement to use for saving @return QDomElement */ -QDomElement XRefProperties::toXml(QDomDocument &xml_document) const +void XRefProperties::toXmlPriv(QDomElement& xml_element) const { + xml_element.setAttribute("type", m_key); - QDomElement xml_element = xml_document.createElement("xref"); - xml_element.setAttribute("type", m_key); + xml_element.setAttribute("showpowerctc", m_show_power_ctc? "true" : "false"); + QString display = m_display == Cross? "cross" : "contacts"; + xml_element.setAttribute("displayhas", display); + QString snap = m_snap_to == Bottom? "bottom" : "label"; + xml_element.setAttribute("snapto", snap); - xml_element.setAttribute("showpowerctc", m_show_power_ctc? "true" : "false"); - QString display = m_display == Cross? "cross" : "contacts"; - xml_element.setAttribute("displayhas", display); - QString snap = m_snap_to == Bottom? "bottom" : "label"; - xml_element.setAttribute("snapto", snap); + QString xrefpos; - QString xrefpos; + QMetaEnum var = QMetaEnum::fromType(); + xml_element.setAttribute("xrefpos", var.valueToKey(m_xref_pos)); - QMetaEnum var = QMetaEnum::fromType(); - xml_element.setAttribute("xrefpos", var.valueToKey(m_xref_pos)); - - int offset = m_offset; - xml_element.setAttribute("offset", QString::number(offset)); - QString master_label = m_master_label; - xml_element.setAttribute("master_label", master_label); - QString slave_label = m_slave_label; - xml_element.setAttribute("slave_label", slave_label); - foreach (QString key, m_prefix.keys()) { - xml_element.setAttribute(key + "prefix", m_prefix.value(key)); - } - - return xml_element; + int offset = m_offset; + xml_element.setAttribute("offset", QString::number(offset)); + QString master_label = m_master_label; + xml_element.setAttribute("master_label", master_label); + QString slave_label = m_slave_label; + xml_element.setAttribute("slave_label", slave_label); + foreach (QString key, m_prefix.keys()) { + xml_element.setAttribute(key + "prefix", m_prefix.value(key)); + } } -/** - @brief XRefProperties::fromXml +/** RETURNS True + @brief XRefProperties::fromXmlPriv Load from xml @param xml_element: QDomElement to use for load */ -bool XRefProperties::fromXml(const QDomElement &xml_element) { - m_show_power_ctc = xml_element.attribute("showpowerctc") == "true"; - QString display = xml_element.attribute("displayhas", "cross"); - display == "cross"? m_display = Cross : m_display = Contacts; - QString snap = xml_element.attribute("snapto", "label"); - snap == "bottom"? m_snap_to = Bottom : m_snap_to = Label; +bool XRefProperties::fromXmlPriv(const QDomElement &xml_element) { - QString xrefpos = xml_element.attribute("xrefpos","Left"); + if (QETXML::propertyBool(xml_element, "showpowerctc", &m_show_power_ctc)) + return false; - QMetaEnum var = QMetaEnum::fromType(); + QString display; + if (QETXML::propertyString(xml_element, "displayhas", &display) != QETXML::PropertyFlags::NotFound) { + display == "cross"? m_display = Cross : m_display = Contacts; + } - if(xml_element.hasAttribute("xrefpos")) - m_xref_pos = Qt::AlignmentFlag(var.keyToValue(xml_element.attribute("xrefpos").toStdString().data())); - else - m_xref_pos = Qt::AlignBottom; - m_offset = xml_element.attribute("offset", "0").toInt(); - m_master_label = xml_element.attribute("master_label", "%f-%l%c"); - m_slave_label = xml_element.attribute("slave_label","(%f-%l%c)"); + QString snap; + if (QETXML::propertyString(xml_element, "snapto", &snap) != QETXML::PropertyFlags::NotFound) { + snap == "bottom"? m_snap_to = Bottom : m_snap_to = Label; + } + + QString xrefpos; + if (QETXML::propertyString(xml_element, "xrefpos", &xrefpos) != QETXML::PropertyFlags::NotFound) { + QMetaEnum var = QMetaEnum::fromType(); + m_xref_pos = Qt::AlignmentFlag(var.keyToValue(xrefpos.toStdString().data())); + } + // TODO: why it compiles without this true?? + QETXML::propertyInteger(xml_element, "offset", &m_offset); + QETXML::propertyString(xml_element, "master_label", &m_master_label); + QETXML::propertyString(xml_element, "slave_label", &m_slave_label); + QString value; foreach (QString key, m_prefix_keys) { - m_prefix.insert(key, xml_element.attribute(key + "prefix")); + if (!QETXML::propertyString(xml_element, key + "prefix", &value)) + m_prefix.insert(key, value); } return true; } diff --git a/sources/properties/xrefproperties.h b/sources/properties/xrefproperties.h index b365cdb54..aa3b4a7e2 100644 --- a/sources/properties/xrefproperties.h +++ b/sources/properties/xrefproperties.h @@ -42,12 +42,11 @@ class XRefProperties : public PropertiesInterface Label }; - void toSettings (QSettings &settings, - const QString = QString()) const override; - void fromSettings (const QSettings &settings, - const QString = QString()) override; - QDomElement toXml (QDomDocument &xml_document) const override; - bool fromXml(const QDomElement &xml_element) override; + void toSettings (QSettings &settings, const QString& = QString()) const override; + void fromSettings (QSettings &settings, + const QString& = QString()) override; + void toXmlPriv(QDomElement&xml_element) const override; + bool fromXmlPriv(const QDomElement &xml_element) override; static QHash defaultProperties(); @@ -80,15 +79,15 @@ class XRefProperties : public PropertiesInterface void setKey(QString& key) {m_key = key;} private: - bool m_show_power_ctc; - DisplayHas m_display; - SnapTo m_snap_to; - Qt::AlignmentFlag m_xref_pos; + bool m_show_power_ctc{true}; + DisplayHas m_display{Cross}; + SnapTo m_snap_to{Bottom}; + Qt::AlignmentFlag m_xref_pos{Qt::AlignBottom}; QHash m_prefix; - QStringList m_prefix_keys; - QString m_master_label; - QString m_slave_label; - int m_offset; + QStringList m_prefix_keys{"power","delay","switch"}; + QString m_master_label{"%f-%l%c"}; + QString m_slave_label{"(%f-%l%c)"}; + int m_offset{0}; QString m_key; }; diff --git a/sources/qet.cpp b/sources/qet.cpp index e7150d06e..9ea80e307 100644 --- a/sources/qet.cpp +++ b/sources/qet.cpp @@ -34,31 +34,6 @@ retourne. @param s Chaine de caractere cense representer une orientation @return l'orientation designee par la chaine de caractere -*/ -Qet::Orientation Qet::orientationFromString(const QString &s) { - QChar c = s[0]; - if (c == 'e') return(Qet::East); - else if (c == 's') return(Qet::South); - else if (c == 'w') return (Qet::West); - else return(Qet::North); -} - -/** - @param o une orientation - @return une chaine de caractere representant l'orientation -*/ -QString Qet::orientationToString(Qet::Orientation o) { - QString ret; - switch(o) { - case Qet::North: ret = "n"; break; - case Qet::East : ret = "e"; break; - case Qet::South: ret = "s"; break; - case Qet::West : ret = "w"; break; - } - return(ret); -} - -/** Indique si deux orientations de Borne sont sur le meme axe (Vertical / Horizontal). @param a La premiere orientation de Borne @param b La seconde orientation de Borne @@ -532,7 +507,7 @@ QString Qet::endTypeToString(const Qet::EndType &end_type) { QET::None est retourne. */ Qet::EndType Qet::endTypeFromString(const QString &string) { - if (string == "simple") return(Qet::Simple); + if (string == "simple") return(Qet::Simple); else if (string == "triangle") return(Qet::Triangle); else if (string == "circle") return(Qet::Circle); else if (string == "diamond") return(Qet::Diamond); @@ -716,9 +691,9 @@ QActionGroup *QET::depthActionGroup(QObject *parent) QActionGroup *action_group = new QActionGroup(parent); QAction *edit_forward = new QAction(QET::Icons::BringForward, QObject::tr("Amener au premier plan"), action_group); - QAction *edit_raise = new QAction(QET::Icons::Raise, QObject::tr("Rapprocher"), action_group); - QAction *edit_lower = new QAction(QET::Icons::Lower, QObject::tr("Éloigner"), action_group); - QAction *edit_backward = new QAction(QET::Icons::SendBackward, QObject::tr("Envoyer au fond"), action_group); + QAction *edit_raise = new QAction(QET::Icons::Raise, QObject::tr("Rapprocher"), action_group); + QAction *edit_lower = new QAction(QET::Icons::Lower, QObject::tr("Éloigner"), action_group); + QAction *edit_backward = new QAction(QET::Icons::SendBackward, QObject::tr("Envoyer au fond"), action_group); edit_forward ->setStatusTip(QObject::tr("Ramène la ou les sélections au premier plan")); edit_raise ->setStatusTip(QObject::tr("Rapproche la ou les sélections")); diff --git a/sources/qetgraphicsitem/conductor.cpp b/sources/qetgraphicsitem/conductor.cpp index 068764e05..df6f69d7a 100644 --- a/sources/qetgraphicsitem/conductor.cpp +++ b/sources/qetgraphicsitem/conductor.cpp @@ -31,6 +31,8 @@ #include "element.h" #include "../QetGraphicsItemModeler/qetgraphicshandleritem.h" +#include "../qetxml.h" + #include #include @@ -78,15 +80,9 @@ class ConductorXmlRetroCompatibility */ Conductor::Conductor(Terminal *p1, Terminal* p2) : terminal1(p1), - terminal2(p2), - m_mouse_over(false), - m_text_item(nullptr), - segments(nullptr), - m_moving_segment(false), - modified_path(false), - has_to_save_profile(false), - must_highlight_(Conductor::None) + terminal2(p2) { + setTagName("conductor"); //set Zvalue at 11 to be upper than the DiagramImageItem and element setZValue(11); m_previous_z_value = zValue(); @@ -111,8 +107,8 @@ Conductor::Conductor(Terminal *p1, Terminal* p2) : } //By default, the 4 profils are nuls -> we must to use priv_calculeConductor - conductor_profiles.insert(Qt::TopLeftCorner, ConductorProfile()); - conductor_profiles.insert(Qt::TopRightCorner, ConductorProfile()); + conductor_profiles.insert(Qt::TopLeftCorner, ConductorProfile()); + conductor_profiles.insert(Qt::TopRightCorner, ConductorProfile()); conductor_profiles.insert(Qt::BottomLeftCorner, ConductorProfile()); conductor_profiles.insert(Qt::BottomRightCorner, ConductorProfile()); @@ -225,7 +221,7 @@ void Conductor::updateConductorPath(const QPointF &p1, Qet::Orientation o1, cons ConductorProfile &conductor_profile = conductor_profiles[currentPathType()]; Q_ASSERT_X(conductor_profile.segmentsCount(QET::Both) > 1, "Conductor::priv_modifieConductor", "pas de points a modifier"); - Q_ASSERT_X(!conductor_profile.isNull(), "Conductor::priv_modifieConductor", "pas de profil utilisable"); + Q_ASSERT_X(!conductor_profile.isNull(), "Conductor::priv_modifieConductor", "pas de profil utilisable"); // recupere les coordonnees fournies des bornes QPointF new_p1 = mapFromScene(p1); @@ -329,10 +325,10 @@ QHash Conductor::shareOffsetBetweenSegments( // on remet le trop-plein dans la reserve d'offset remaining_offset += qAbs(segments_hash[csp]) * getSign(local_offset); - //qDebug() << " trop-plein de" << qAbs(segments_hash[csp]) * getSign(local_offset) << "remaining_offset =" << remaining_offset; + //qDebug() << " trop-plein de" << qAbs(segments_hash[csp]) * getSign(local_offset) << "remaining_offset =" << remaining_offset; segments_hash[csp] = 0.0; } else { - //qDebug() << " offset local de" << local_offset << "accepte"; + //qDebug() << " offset local de" << local_offset << "accepte"; } } } @@ -364,17 +360,17 @@ void Conductor::generateConductorPath(const QPointF &p1, Qet::Orientation o1, co // distingue le depart de l'arrivee : le trajet se fait toujours de gauche a droite (apres prolongation) if (newp1.x() <= newp2.x()) { - depart = newp1; - arrivee = newp2; - depart0 = sp1; - arrivee0 = sp2; + depart = newp1; + arrivee = newp2; + depart0 = sp1; + arrivee0 = sp2; ori_depart = o1; ori_arrivee = o2; } else { - depart = newp2; - arrivee = newp1; - depart0 = sp2; - arrivee0 = sp1; + depart = newp2; + arrivee = newp1; + depart0 = sp2; + arrivee0 = sp1; ori_depart = o2; ori_arrivee = o1; } @@ -587,36 +583,16 @@ ConductorTextItem *Conductor::textItem() const @return true si l'element XML represente bien un Conducteur ; false sinon */ bool Conductor::valideXml(QDomElement &e){ - // verifie le nom du tag - if (e.tagName() != "conductor") return(false); - // verifie la presence des attributs minimaux - if (!e.hasAttribute("terminal1")) return(false); - if (!e.hasAttribute("terminal2")) return(false); +// // TODO: seems to short! (see fromXML) +// if (QETXML::propertyDouble(e, "x") || +// QETXML::propertyDouble(e, "y")) +// return false; - bool conv_ok; - // parse l'abscisse - if (e.hasAttribute("element1")) { - if (QUuid(e.attribute("element1")).isNull()) - return false; - if (QUuid(e.attribute("terminal1")).isNull()) - return false; - } else { - e.attribute("terminal1").toInt(&conv_ok); - if (!conv_ok) return(false); - } +// if (QETXML::propertyBool(e, "freezeLabel")) +// return false; - // parse l'ordonnee - if (e.hasAttribute("element2")) { - if (QUuid(e.attribute("element2")).isNull()) - return false; - if (QUuid(e.attribute("terminal2")).isNull()) - return false; - } else { - e.attribute("terminal2").toInt(&conv_ok); - if (!conv_ok) return(false); - } - return(true); + return true; } /** @@ -989,16 +965,26 @@ void Conductor::pointsToSegments(const QList& points_list) { @param dom_element @return true is loading success else return false */ -bool Conductor::fromXml(QDomElement &dom_element) +bool Conductor::fromXmlPriv(const QDomElement &dom_element) { - setPos(dom_element.attribute("x", nullptr).toDouble(), - dom_element.attribute("y", nullptr).toDouble()); + double x=0, y=0; + QETXML::propertyDouble(dom_element, "x", &x); + QETXML::propertyDouble(dom_element, "y", &y); + setPos(x, y); bool return_ = pathFromXml(dom_element); m_text_item -> fromXml(dom_element); - ConductorProperties pr; - pr.fromXml(dom_element); + + auto prs = QETXML::findInDomElement(dom_element, ConductorProperties::xmlTagName()); + ConductorProperties pr; + if (!prs.isEmpty()) { + pr.fromXml(prs.first()); + } else { + // legacy + // added in 0.9 remove in later version! + pr.fromXml(dom_element); + } //Load Sequential Values if (dom_element.hasAttribute("sequ_1") || dom_element.hasAttribute("sequf_1") || dom_element.hasAttribute("seqt_1") || dom_element.hasAttribute("seqtf_1") || dom_element.hasAttribute("seqh_1") || dom_element.hasAttribute("sequf_1")) @@ -1006,15 +992,15 @@ bool Conductor::fromXml(QDomElement &dom_element) else m_autoNum_seq.fromXml(dom_element.firstChildElement("sequentialNumbers")); - m_freeze_label = dom_element.attribute("freezeLabel") == "true"? true : false; - + QETXML::propertyBool(dom_element, "freezeLabel", &m_freeze_label); setProperties(pr); return return_; } -/** - @brief Conductor::toXml +// does not support legacy method +/*! + @brief Conductor::toXmlPriv Exporte les caracteristiques du conducteur sous forme d'une element XML. @param dom_document : Le document XML a utiliser pour creer l'element XML @@ -1023,70 +1009,122 @@ bool Conductor::fromXml(QDomElement &dom_element) bornes dans le document XML et leur adresse en memoire @return Un element XML representant le conducteur */ -QDomElement Conductor::toXml(QDomDocument &dom_document, - QHash &table_adr_id) const -{ - QDomElement dom_element = dom_document.createElement("conductor"); +void Conductor::toXmlPriv(QDomElement& dom_element) const { - dom_element.setAttribute("x", QString::number(pos().x())); - dom_element.setAttribute("y", QString::number(pos().y())); + dom_element.setAttribute("x", QString::number(pos().x())); + dom_element.setAttribute("y", QString::number(pos().y())); - // Terminal is uniquely identified by the uuid of the terminal and the element - if (terminal1->uuid().isNull()) { - // legacy method to identify the terminal - dom_element.setAttribute("terminal1", table_adr_id.value(terminal1)); // for backward compability - } else { - dom_element.setAttribute("element1", terminal1->parentElement()->uuid().toString()); - dom_element.setAttribute("terminal1", terminal1->uuid().toString()); - } + // Terminal is uniquely identified by the uuid of the terminal and the element + if (terminal1->uuid().isNull()) { + // legacy method to identify the terminal + dom_element.setAttribute("terminal1", terminal1->ID()); // for backward compability + } else { + dom_element.setAttribute("element1", terminal1->parentElement()->uuid().toString()); + dom_element.setAttribute("terminal1", terminal1->uuid().toString()); + } - if (terminal2->uuid().isNull()) { - // legacy method to identify the terminal - dom_element.setAttribute("terminal2", table_adr_id.value(terminal2)); // for backward compability - } else { - dom_element.setAttribute("element2", terminal2->parentElement()->uuid().toString()); - dom_element.setAttribute("terminal2", terminal2->uuid().toString()); - } - dom_element.setAttribute("freezeLabel", m_freeze_label? "true" : "false"); + if (terminal2->uuid().isNull()) { + // legacy method to identify the terminal + dom_element.setAttribute("terminal2", terminal2->ID()); // for backward compability + } else { + dom_element.setAttribute("element2", terminal2->parentElement()->uuid().toString()); + dom_element.setAttribute("terminal2", terminal2->uuid().toString()); + } + dom_element.setAttribute("freezeLabel", m_freeze_label? "true" : "false"); - // on n'exporte les segments du conducteur que si ceux-ci ont - // ete modifies par l'utilisateur - if (modified_path) - { - // parcours et export des segments - QDomElement current_segment; - foreach(ConductorSegment *segment, segmentsList()) - { - current_segment = dom_document.createElement("segment"); - current_segment.setAttribute("orientation", segment -> isHorizontal() ? "horizontal" : "vertical"); - current_segment.setAttribute("length", QString("%1").arg(segment -> length())); - dom_element.appendChild(current_segment); - } - } + // on n'exporte les segments du conducteur que si ceux-ci ont + // ete modifies par l'utilisateur + if (modified_path) + { + // parcours et export des segments + QDomElement current_segment; + foreach(ConductorSegment *segment, segmentsList()) + { + current_segment = dom_element.ownerDocument().createElement("segment"); + current_segment.setAttribute("orientation", segment -> isHorizontal() ? "horizontal" : "vertical"); + current_segment.setAttribute("length", QString("%1").arg(segment -> length())); + dom_element.appendChild(current_segment); + } + } + QDomDocument doc = dom_element.ownerDocument(); + QDomElement dom_seq = m_autoNum_seq.toXml(doc); + dom_element.appendChild(dom_seq); - QDomElement dom_seq = m_autoNum_seq.toXml(dom_document); - dom_element.appendChild(dom_seq); - - // Export the properties and text - m_properties. toXml(dom_element); - if(m_text_item->wasMovedByUser()) - { - dom_element.setAttribute("userx", QString::number(m_text_item->pos().x())); - dom_element.setAttribute("usery", QString::number(m_text_item->pos().y())); - } - if(m_text_item->wasRotateByUser()) - dom_element.setAttribute("rotation", QString::number(m_text_item->rotation())); - - return(dom_element); + // Export the properties and text + dom_element.appendChild(m_properties. toXml(doc)); + if(m_text_item->wasMovedByUser()) + { + dom_element.setAttribute("userx", QString::number(m_text_item->pos().x())); + dom_element.setAttribute("usery", QString::number(m_text_item->pos().y())); + } + if(m_text_item->wasRotateByUser()) + dom_element.setAttribute("rotation", QString::number(m_text_item->rotation())); } /** - @brief Conductor::pathFromXml - Generate the path (of the line) from xml file by checking the segments in the xml - file - @param e - @return true if generate path success else return false + Exporte les caracteristiques du conducteur sous forme d'une element XML. + @param d Le document XML a utiliser pour creer l'element XML + @param table_adr_id Hash stockant les correspondances entre les ids des + bornes dans le document XML et leur adresse en memoire + @return Un element XML representant le conducteur +*/ +//QDomElement Conductor::toXml(QDomDocument &dom_document, QHash &table_adr_id) const +//{ +// QDomElement dom_element = dom_document.createElement("conductor"); + +// dom_element.setAttribute("x", QString::number(pos().x())); +// dom_element.setAttribute("y", QString::number(pos().y())); + +// // Terminal is uniquely identified by the uuid of the terminal and the element +// if (terminal1->uuid().isNull()) { +// // legacy method to identify the terminal +// dom_element.setAttribute("terminal1", table_adr_id.value(terminal1)); // for backward compability +// } else { +// dom_element.setAttribute("element1", terminal1->parentElement()->uuid().toString()); +// dom_element.setAttribute("terminal1", terminal1->uuid().toString()); +// } + +// if (terminal2->uuid().isNull()) { +// // legacy method to identify the terminal +// dom_element.setAttribute("terminal2", table_adr_id.value(terminal2)); // for backward compability +// } else { +// dom_element.setAttribute("element2", terminal2->parentElement()->uuid().toString()); +// dom_element.setAttribute("terminal2", terminal2->uuid().toString()); +// } +// dom_element.setAttribute("freezeLabel", m_freeze_label? "true" : "false"); + +// // on n'exporte les segments du conducteur que si ceux-ci ont +// // ete modifies par l'utilisateur +// if (modified_path) +// { +// // parcours et export des segments +// QDomElement current_segment; +// foreach(ConductorSegment *segment, segmentsList()) +// { +// current_segment = dom_document.createElement("segment"); +// current_segment.setAttribute("orientation", segment -> isHorizontal() ? "horizontal" : "vertical"); +// current_segment.setAttribute("length", QString("%1").arg(segment -> length())); +// dom_element.appendChild(current_segment); +// } +// } + +// QDomElement dom_seq = m_autoNum_seq.toXml(dom_document); +// dom_element.appendChild(dom_seq); + +// // Export the properties and text +// m_properties.toXml(dom_document); +// if(m_text_item->wasMovedByUser()) +// { +// dom_element.setAttribute("userx", QString::number(m_text_item->pos().x())); +// dom_element.setAttribute("usery", QString::number(m_text_item->pos().y())); +// } +// if(m_text_item->wasRotateByUser()) +// dom_element.setAttribute("rotation", QString::number(m_text_item->rotation())); + +// return(dom_element); +//} + +/** */ bool Conductor::pathFromXml(const QDomElement &e) { // parcourt les elements XML "segment" et en extrait deux listes de longueurs @@ -1098,14 +1136,21 @@ bool Conductor::pathFromXml(const QDomElement &e) { if (current_segment.isNull() || current_segment.tagName() != "segment") continue; // le segment doit avoir une longueur - if (!current_segment.hasAttribute("length")) continue; + qreal segment_length; + if (QETXML::propertyDouble(current_segment, "length", & segment_length)) + continue; - // cette longueur doit etre un reel - bool ok; - qreal segment_length = current_segment.attribute("length").toDouble(&ok); - if (!ok) continue; + bool isHorizontal = false; + QString orientation; + if (QETXML::propertyString(current_segment, "orientation", &orientation) == QETXML::PropertyFlags::Success) { + if (orientation == "horizontal") + isHorizontal = true; + } else { + qDebug() << "PathFromXML failed"; + return false; + } - if (current_segment.attribute("orientation") == "horizontal") { + if (isHorizontal) { segments_x << segment_length; segments_y << 0.0; } else { @@ -1237,7 +1282,7 @@ ConductorSegment *Conductor::middleSegment() QPointF Conductor::posForText(Qt::Orientations &flag) { - ConductorSegment *segment = segments; + ConductorSegment *segment = segments; bool all_segment_is_vertical = true; bool all_segment_is_horizontal = true; @@ -1356,7 +1401,7 @@ void Conductor::calculateTextItemPosition() } //Adjust the position of text if his rotation - //is 0° or 270°, to be exactly centered to the conductor + //is 0?? or 270??, to be exactly centered to the conductor if (m_text_item -> rotation() == 0) { text_pos.rx() -= m_text_item -> boundingRect().width()/2; @@ -1633,12 +1678,12 @@ void Conductor::displayedTextChanged() new_value.setValue(new_properties); - QUndoCommand *undo = new QUndoCommand(tr("Modifier les propriétés d'un conducteur", "undo caption")); + QUndoCommand *undo = new QUndoCommand(tr("Modifier les propri??t??s d'un conducteur", "undo caption")); new QPropertyUndoCommand(this, "properties", old_value, new_value, undo); if (!relatedPotentialConductors().isEmpty()) { - undo->setText(tr("Modifier les propriétés de plusieurs conducteurs", "undo caption")); + undo->setText(tr("Modifier les propri??t??s de plusieurs conducteurs", "undo caption")); foreach (Conductor *potential_conductor, relatedPotentialConductors()) { @@ -1724,7 +1769,7 @@ QSet Conductor::relatedPotentialConductors(const bool all_diagram, */ QETDiagramEditor* Conductor::diagramEditor() const { - if (!diagram()) return nullptr; + if (!diagram()) return nullptr; if (diagram() -> views().isEmpty()) return nullptr; QWidget *w = const_cast(diagram() -> views().at(0)); diff --git a/sources/qetgraphicsitem/conductor.h b/sources/qetgraphicsitem/conductor.h index 6d3837545..da1287860 100644 --- a/sources/qetgraphicsitem/conductor.h +++ b/sources/qetgraphicsitem/conductor.h @@ -20,6 +20,8 @@ #include "../autoNum/assignvariables.h" #include "../conductorproperties.h" +#include "../conductorproperties.h" +#include "../properties/propertiesinterface.h" #include class ConductorProfile; @@ -39,7 +41,7 @@ typedef QHash ConductorProfilesGroup; This class represents a conductor, i.e. a wire between two element terminals. */ -class Conductor : public QGraphicsObject +class Conductor : public QGraphicsObject, public PropertiesInterface { Q_OBJECT @@ -100,11 +102,10 @@ class Conductor : public QGraphicsObject public: static bool valideXml (QDomElement &); - bool fromXml (QDomElement &); - QDomElement toXml ( - QDomDocument &, - QHash &) const; + bool fromXmlPriv(const QDomElement &) override; + void toXmlPriv(QDomElement&dom_element) const override; + void toSettings(QSettings &, const QString & = QString()) const override {} + void fromSettings(QSettings &, const QString & = QString()) override {} private: bool pathFromXml(const QDomElement &); @@ -137,7 +138,7 @@ class Conductor : public QGraphicsObject {return m_autoNum_seq;} void setSequenceNum(const autonum::sequentialNumbers& sn); - QList junctions() const; + QList junctions() const; private: void setUpConnectionForFormula( @@ -181,28 +182,28 @@ class Conductor : public QGraphicsObject QVector m_handler_vector; int m_vector_index = -1; - bool m_mouse_over; + bool m_mouse_over{false}; /// Functional properties ConductorProperties m_properties; /// Text input for non simple, non-singleline conductors - ConductorTextItem *m_text_item; + ConductorTextItem *m_text_item{nullptr}; /// Segments composing the conductor - ConductorSegment *segments; + ConductorSegment *segments{nullptr}; /// Attributs related to mouse interaction - bool m_moving_segment; + bool m_moving_segment{false}; int moved_point; qreal m_previous_z_value; ConductorSegment *m_moved_segment; QPointF before_mov_text_pos_; /// Whether the conductor was manually modified by users - bool modified_path; + bool modified_path{false}; /// Whether the current profile should be saved as soon as possible - bool has_to_save_profile; + bool has_to_save_profile{false}; /// conductor profile: "photography" of what the conductor is supposed to look /// like - there is one profile per kind of traject ConductorProfilesGroup conductor_profiles; /// Define whether and how the conductor should be highlighted - Highlight must_highlight_; + Highlight must_highlight_{Conductor::None}; bool m_valid; bool m_freeze_label = false; diff --git a/sources/qetgraphicsitem/conductortextitem.cpp b/sources/qetgraphicsitem/conductortextitem.cpp index b9f2e5834..22e1cef0a 100644 --- a/sources/qetgraphicsitem/conductortextitem.cpp +++ b/sources/qetgraphicsitem/conductortextitem.cpp @@ -21,15 +21,15 @@ #include "../diagramcommands.h" #include "../qetgraphicsitem/conductor.h" +#include "../qetxml.h" + /** Constructeur @param parent_conductor Conducteur auquel ce texte est rattache */ ConductorTextItem::ConductorTextItem(Conductor *parent_conductor) : DiagramTextItem(parent_conductor), - parent_conductor_(parent_conductor), - moved_by_user_(false), - rotate_by_user_(false) + parent_conductor_(parent_conductor) { setAcceptHoverEvents(true); } @@ -69,13 +69,17 @@ Conductor *ConductorTextItem::parentConductor() const @param e */ void ConductorTextItem::fromXml(const QDomElement &e) { - if (e.hasAttribute("userx")) { - setPos(e.attribute("userx").toDouble(), - e.attribute("usery").toDouble()); + + double userx=0, usery=0; + if (QETXML::propertyDouble(e, "userx", &userx) == QETXML::PropertyFlags::Success && + QETXML::propertyDouble(e, "usery", &usery) == QETXML::PropertyFlags::Success) { + setPos(userx, usery); moved_by_user_ = true; } - if (e.hasAttribute("rotation")) { - setRotation(e.attribute("rotation").toDouble()); + + double rotation; + if (QETXML::propertyDouble(e, "rotation", &rotation) == QETXML::PropertyFlags::Success) { + setRotation(rotation); rotate_by_user_ = true; } } diff --git a/sources/qetgraphicsitem/conductortextitem.h b/sources/qetgraphicsitem/conductortextitem.h index 4c51939ce..025fa1a34 100644 --- a/sources/qetgraphicsitem/conductortextitem.h +++ b/sources/qetgraphicsitem/conductortextitem.h @@ -52,7 +52,7 @@ class ConductorTextItem : public DiagramTextItem protected: void mousePressEvent (QGraphicsSceneMouseEvent *event) override; - void mouseMoveEvent (QGraphicsSceneMouseEvent *event) override; + void mouseMoveEvent (QGraphicsSceneMouseEvent *event) override; void mouseReleaseEvent (QGraphicsSceneMouseEvent *event) override; void hoverEnterEvent(QGraphicsSceneHoverEvent *) override; void hoverLeaveEvent(QGraphicsSceneHoverEvent *) override; @@ -61,8 +61,8 @@ class ConductorTextItem : public DiagramTextItem // attributes private: Conductor *parent_conductor_; - bool moved_by_user_; - bool rotate_by_user_; + bool moved_by_user_{false}; + bool rotate_by_user_{false}; QPointF before_mov_pos_; }; #endif diff --git a/sources/qetgraphicsitem/dynamicelementtextitem.cpp b/sources/qetgraphicsitem/dynamicelementtextitem.cpp index 60859eeef..68ca7f201 100644 --- a/sources/qetgraphicsitem/dynamicelementtextitem.cpp +++ b/sources/qetgraphicsitem/dynamicelementtextitem.cpp @@ -86,36 +86,36 @@ DynamicElementTextItem::DynamicElementTextItem() @param dom_doc @return */ -QDomElement DynamicElementTextItem::toXml(QDomDocument &dom_doc) const +QDomElement DynamicElementTextItem::toXml(QDomDocument& dom_doc) const { - QDomElement root_element = dom_doc.createElement(xmlTagName()); + QDomElement root_element = dom_doc.createElement(xmlTagName()); - root_element.setAttribute("x", QString::number(pos().x())); - root_element.setAttribute("y", QString::number(pos().y())); - root_element.setAttribute("rotation", QString::number(QET::correctAngle(rotation()))); - root_element.setAttribute("uuid", m_uuid.toString()); - root_element.setAttribute("frame", m_frame? "true" : "false"); - root_element.setAttribute("text_width", QString::number(m_text_width)); - root_element.setAttribute("font", font().toString()); - root_element.setAttribute("keep_visual_rotation", m_keep_visual_rotation ? "true" : "false"); + root_element.setAttribute("x", QString::number(pos().x())); + root_element.setAttribute("y", QString::number(pos().y())); + root_element.setAttribute("rotation", QString::number(QET::correctAngle(rotation()))); + root_element.setAttribute("uuid", m_uuid.toString()); + root_element.setAttribute("frame", m_frame? "true" : "false"); + root_element.setAttribute("text_width", QString::number(m_text_width)); + root_element.setAttribute("font", font().toString()); + root_element.setAttribute("keep_visual_rotation", m_keep_visual_rotation ? "true" : "false"); QMetaEnum me = textFromMetaEnum(); - root_element.setAttribute("text_from", me.valueToKey(m_text_from)); + root_element.setAttribute("text_from", me.valueToKey(m_text_from)); me = QMetaEnum::fromType(); if(this->alignment() &Qt::AlignRight) - root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignRight)); + root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignRight)); else if(this->alignment() &Qt::AlignLeft) - root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignLeft)); + root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignLeft)); else if(this->alignment() &Qt::AlignHCenter) - root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignHCenter)); + root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignHCenter)); if(this->alignment() &Qt::AlignBottom) - root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignBottom)); + root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignBottom)); else if(this->alignment() & Qt::AlignTop) - root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignTop)); + root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignTop)); else if(this->alignment() &Qt::AlignVCenter) - root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignVCenter)); + root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignVCenter)); QDomElement dom_text = dom_doc.createElement("text"); @@ -216,7 +216,7 @@ void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt) setColor(QColor(dom_color.text())); //Force the update of the displayed text - setTextFrom(m_text_from); + setTextFrom(m_text_from); // TODO: does not update because there is a retrun inside if the textfrom argument is the same as m_text_from QGraphicsTextItem::setPos(dom_elmt.attribute("x", QString::number(0)).toDouble(), dom_elmt.attribute("y", QString::number(0)).toDouble()); @@ -1323,12 +1323,12 @@ void DynamicElementTextItem::updateXref() m_slave_Xref_item->setFont(QETApp::diagramTextsFont(5)); m_slave_Xref_item->installSceneEventFilter(this); - m_update_slave_Xref_connection << connect(m_master_element.data(), &Element::xChanged, this, &DynamicElementTextItem::updateXref); - m_update_slave_Xref_connection << connect(m_master_element.data(), &Element::yChanged, this, &DynamicElementTextItem::updateXref); - m_update_slave_Xref_connection << connect(m_master_element.data(), &Element::elementInfoChange, this, &DynamicElementTextItem::updateXref); - m_update_slave_Xref_connection << connect(diagram()->project(), &QETProject::projectDiagramsOrderChanged, this, &DynamicElementTextItem::updateXref); - m_update_slave_Xref_connection << connect(diagram()->project(), &QETProject::diagramRemoved, this, &DynamicElementTextItem::updateXref); - m_update_slave_Xref_connection << connect(diagram()->project(), &QETProject::XRefPropertiesChanged, this, &DynamicElementTextItem::updateXref); + m_update_slave_Xref_connection << connect(m_master_element.data(), &Element::xChanged, this, &DynamicElementTextItem::updateXref); + m_update_slave_Xref_connection << connect(m_master_element.data(), &Element::yChanged, this, &DynamicElementTextItem::updateXref); + m_update_slave_Xref_connection << connect(m_master_element.data(), &Element::elementInfoChange, this, &DynamicElementTextItem::updateXref); + m_update_slave_Xref_connection << connect(diagram()->project(), &QETProject::projectDiagramsOrderChanged, this, &DynamicElementTextItem::updateXref); + m_update_slave_Xref_connection << connect(diagram()->project(), &QETProject::diagramRemoved, this, &DynamicElementTextItem::updateXref); + m_update_slave_Xref_connection << connect(diagram()->project(), &QETProject::XRefPropertiesChanged, this, &DynamicElementTextItem::updateXref); } else m_slave_Xref_item->setPlainText(xref_label); diff --git a/sources/qetgraphicsitem/dynamicelementtextitem.h b/sources/qetgraphicsitem/dynamicelementtextitem.h index 847376c85..ed6860546 100644 --- a/sources/qetgraphicsitem/dynamicelementtextitem.h +++ b/sources/qetgraphicsitem/dynamicelementtextitem.h @@ -82,7 +82,7 @@ class DynamicElementTextItem : public DiagramTextItem DynamicElementTextItem(const DynamicElementTextItem &); public: - QDomElement toXml(QDomDocument &dom_doc) const override; + QDomElement toXml(QDomDocument&) const override; void fromXml(const QDomElement &dom_elmt) override; Element *parentElement() const; @@ -160,7 +160,7 @@ class DynamicElementTextItem : public DiagramTextItem QList m_formula_connection, m_update_slave_Xref_connection; - QColor m_user_color; + QColor m_user_color{QColor()}; bool m_frame = false, m_first_scene_change = true; diff --git a/sources/qetgraphicsitem/element.cpp b/sources/qetgraphicsitem/element.cpp index 449e73cd4..0a57c5d2a 100644 --- a/sources/qetgraphicsitem/element.cpp +++ b/sources/qetgraphicsitem/element.cpp @@ -98,7 +98,8 @@ Element::Element( } } int elmt_state; - buildFromXml(location.xml(), &elmt_state); + qDebug() << "\tCollection Path: " << location.collectionPath(); + buildFromXml(location.xml(), &elmt_state); // build from the collection definition if (state) { *state = elmt_state; } @@ -351,8 +352,8 @@ void Element::drawSelection( Q_UNUSED(options); painter -> save(); // Annulation des renderhints - painter -> setRenderHint(QPainter::Antialiasing, false); - painter -> setRenderHint(QPainter::TextAntialiasing, false); + painter -> setRenderHint(QPainter::Antialiasing, false); + painter -> setRenderHint(QPainter::TextAntialiasing, false); painter -> setRenderHint(QPainter::SmoothPixmapTransform, false); // Dessin du cadre de selection en gris QPen t; @@ -401,7 +402,7 @@ void Element::drawHighlight( /** @brief Element::buildFromXml - Build this element from an xml description + Build this element from an xml description (from the collection) @param xml_def_elmt @param state Optional pointer which define the status of build @@ -434,9 +435,9 @@ bool Element::buildFromXml(const QDomElement &xml_def_elmt, int *state) if (conv_ok && QET::version.toDouble() < element_version) { std::cerr << qPrintable( - QObject::tr("Avertissement : l'élément " - " a été enregistré avec une version" - " ultérieure de QElectroTech.") + QObject::tr("Avertissement : l'??l??ment " + " a ??t?? enregistr?? avec une version" + " ult??rieure de QElectroTech.") ) << std::endl; } } @@ -518,11 +519,15 @@ bool Element::buildFromXml(const QDomElement &xml_def_elmt, int *state) if (qde.isNull()) continue; - if (parseElement(qde)) { + qDebug() << "\t\tElement.cpp:buildFromXml;parseElement: " << qde.tagName(); + + if (parseElement(qde)) { // TODO: why lines are not parsed here? + qDebug() << "\t\t\tParsing Element success"; ++ parsed_elements_count; } else { + qDebug() << "\t\t\tParsing Element no success"; if (state) *state = 7; m_state = QET::GIOK; @@ -548,13 +553,11 @@ bool Element::buildFromXml(const QDomElement &xml_def_elmt, int *state) m_state = QET::GIOK; return(false); } - else - { - if (state) - *state = 0; - m_state = QET::GIOK; - return(true); - } + + if (state) + *state = 0; + m_state = QET::GIOK; + return(true); } /** @@ -565,8 +568,8 @@ bool Element::buildFromXml(const QDomElement &xml_def_elmt, int *state) */ bool Element::parseElement(const QDomElement &dom) { - if (dom.tagName() == "terminal") return(parseTerminal(dom)); - else if (dom.tagName() == "input") return(parseInput(dom)); + if (dom.tagName() == "terminal") return(parseTerminal(dom)); + else if (dom.tagName() == "input") return(parseInput(dom)); else if (dom.tagName() == "dynamic_text") return(parseDynamicText(dom)); else return(true); } @@ -658,13 +661,11 @@ DynamicElementTextItem *Element::parseDynamicText( */ Terminal *Element::parseTerminal(const QDomElement &dom_element) { - TerminalData* data = new TerminalData(); - if (!data->fromXml(dom_element)) { - delete data; + if (!Terminal::valideXml(dom_element)) return nullptr; - } - Terminal *new_terminal = new Terminal(data, this); + Terminal *new_terminal = new Terminal(0, 0, Qet::Orientation::North, this); // does not matter which values are typed in here, because they get overwritten by the fromXML() function + new_terminal->fromXml(dom_element); m_terminals << new_terminal; //Sort from top to bottom and left to rigth @@ -679,7 +680,7 @@ Terminal *Element::parseTerminal(const QDomElement &dom_element) return (a->dockConductor().y() < b->dockConductor().y()); }); - return(new_terminal); + return(new_terminal); // TODO: makes no sense } /** @@ -693,8 +694,8 @@ bool Element::valideXml(QDomElement &e) { // verifie la presence des attributs minimaux if (!e.hasAttribute("type")) return(false); - if (!e.hasAttribute("x")) return(false); - if (!e.hasAttribute("y")) return(false); + if (!e.hasAttribute("x")) return(false); + if (!e.hasAttribute("y")) return(false); bool conv_ok; // parse l'abscisse @@ -721,15 +722,14 @@ bool Element::valideXml(QDomElement &e) { */ bool Element::fromXml( QDomElement &e, - QHash &table_id_adr) + QHash &table_id_adr) { m_state = QET::GILoadingFromXml; /* les bornes vont maintenant etre recensees pour associer leurs id a leur adresse reelle ce recensement servira lors de la mise en place des fils */ - QList liste_terminals; + QList liste_terminals; // terminals in the element in the diagram foreach(QDomElement qde, QET::findInDomElement(e, "terminals", "terminal")) { if (Terminal::valideXml(qde)) liste_terminals << qde; @@ -737,15 +737,29 @@ bool Element::fromXml( QHash priv_id_adr; int terminals_non_trouvees = 0; - foreach(QGraphicsItem *qgi, childItems()) { + // The added childs from the collection now must match with the terminals from the diagram. Iterate through + // all Terminals in the collection and in the diagram to link them together + for(QGraphicsItem *qgi: childItems()) { // TODO: Where the Terminals are added as childs? if (Terminal *p = qgraphicsitem_cast(qgi)) { bool terminal_trouvee = false; - foreach(QDomElement qde, liste_terminals) { - if (p -> fromXml(qde)) { - priv_id_adr.insert( - qde.attribute( - "id").toInt(), - p); + for(QDomElement qde: liste_terminals) { + // The position in the collection element definition is the origin position (originPos). + // The position in the diagram element definition is the position where the conductor is connected (dock position) + // Therefore a simple operator overloading is not possible. + Terminal diagramTerminal(0,0, Qet::Orientation::East); + diagramTerminal.fromXml(qde); + QPointF dockPos1 = diagramTerminal.originPos(); // position here is directly the dock_elmt_ position (stored in the diagram) + QPointF dockPos2 = p->dockPos(); + if (qFuzzyCompare(dockPos1.x(), dockPos2.x()) && + qFuzzyCompare(dockPos1.y(), dockPos2.y()) && + p->orientation() == diagramTerminal.orientation()) { // check if the part in the collection is the same as in the diagram stored + qDebug() << "Matching Terminal found."; + // store id for legacy purpose, because when opening a old project in the collection the terminal does not have an uuid. Therefore the id must be used + if (p->uuid().isNull()) { + p->setID(qde.attribute("id").toInt()); + } + + priv_id_adr.insert(qde.attribute("id").toInt(), p); terminal_trouvee = true; // We used to break here, because we did not expect // several terminals to share the same position. @@ -758,6 +772,7 @@ bool Element::fromXml( if (terminals_non_trouvees > 0) { + qDebug() << "element.cpp: Element::fromXML; Elements not found: " << terminals_non_trouvees; m_state = QET::GIOK; return(false); } @@ -775,15 +790,15 @@ bool Element::fromXml( } // copie des associations id / adr foreach(int id_trouve, priv_id_adr.keys()) { - table_id_adr.insert(id_trouve, + table_id_adr.insert(id_trouve, priv_id_adr.value(id_trouve)); } } //load uuid of connected elements - QList uuid_list = QET::findInDomElement(e, - "links_uuids", - "link_uuid"); + QList uuid_list = QET::findInDomElement(e, "links_uuids", "link_uuid"); + foreach (QDomElement qdo, uuid_list) tmp_uuids_link << qdo.attribute("uuid"); + foreach (QDomElement qdo, uuid_list) #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt 6: remove tmp_uuids_link << qdo.attribute("uuid"); @@ -837,7 +852,7 @@ bool Element::fromXml( //************************// //***Dynamic texts item***// - //************************// + //************************// read from the diagram section for (const QDomElement& qde : QET::findInDomElement( e, "dynamic_texts", @@ -892,9 +907,7 @@ bool Element::fromXml( \~French L'element XML representant cet element electrique */ QDomElement Element::toXml( - QDomDocument &document, - QHash &table_adr_id) const + QDomDocument &document) const { QDomElement element = document.createElement("element"); @@ -921,18 +934,6 @@ QDomElement Element::toXml( element.setAttribute("z", QString::number(this->zValue())); element.setAttribute("orientation", QString::number(orientation())); - /* get the first id to use for the bounds of this element - * recupere le premier id a utiliser pour les bornes de cet element */ - int id_terminal = 0; - if (!table_adr_id.isEmpty()) { - // trouve le plus grand id - int max_id_t = -1; - foreach (int id_t, table_adr_id.values()) { - if (id_t > max_id_t) max_id_t = id_t; - } - id_terminal = max_id_t + 1; - } - // registration of device terminals // enregistrement des bornes de l'appareil QDomElement xml_terminals = document.createElement("terminals"); @@ -941,8 +942,10 @@ QDomElement Element::toXml( foreach(Terminal *t, terminals()) { // alors on enregistre la borne QDomElement terminal = t -> toXml(document); - terminal.setAttribute("id", id_terminal); // for backward compatibility - table_adr_id.insert(t, id_terminal ++); + if (t->ID() > 0) { + // for backward compatibility + terminal.setAttribute("id", t->ID()); // for backward compatibility + } xml_terminals.appendChild(terminal); } element.appendChild(xml_terminals); diff --git a/sources/qetgraphicsitem/element.h b/sources/qetgraphicsitem/element.h index ca4d8fa69..2087cf379 100644 --- a/sources/qetgraphicsitem/element.h +++ b/sources/qetgraphicsitem/element.h @@ -1,4 +1,4 @@ -/* +/* Copyright 2006-2021 The QElectroTech Team This file is part of QElectroTech. @@ -39,7 +39,7 @@ class ElementTextItemGroup; /** This is the base class for electrical elements. */ -class Element : public QetGraphicsItem +class Element : public QetGraphicsItem // TODO: derive from propertiesInterface! { friend class DiagramEventAddElement; @@ -140,14 +140,8 @@ class Element : public QetGraphicsItem QPoint hotspot() const; void editProperty() override; static bool valideXml(QDomElement &); - virtual bool fromXml( - QDomElement &, - QHash &); - virtual QDomElement toXml( - QDomDocument &, - QHash &) const; + virtual bool fromXml(QDomElement &, QHash &); + virtual QDomElement toXml(QDomDocument &) const; QUuid uuid() const; int orientation() const; @@ -188,7 +182,7 @@ class Element : public QetGraphicsItem */ QString linkTypeToString() const; - void newUuid() {m_uuid = QUuid::createUuid();} //create new uuid for this element + void newUuid() {m_uuid = QUuid::createUuid();} //create new uuid for this element protected: void drawAxes(QPainter *, const QStyleOptionGraphicsItem *); @@ -225,9 +219,9 @@ class Element : public QetGraphicsItem protected: //ATTRIBUTES related to linked element QList connected_elements; - QList tmp_uuids_link; - QUuid m_uuid; - kind m_link_type = Element::Simple; + QList tmp_uuids_link; + QUuid m_uuid; + kind m_link_type = Element::Simple; //ATTRIBUTES related to informations DiagramContext m_kind_informations; diff --git a/sources/qetgraphicsitem/elementtextitemgroup.cpp b/sources/qetgraphicsitem/elementtextitemgroup.cpp index c36b5be74..f0dde3aab 100644 --- a/sources/qetgraphicsitem/elementtextitemgroup.cpp +++ b/sources/qetgraphicsitem/elementtextitemgroup.cpp @@ -317,8 +317,8 @@ void ElementTextItemGroup::setHoldToBottomPage(bool hold) &Element::linkedElementChanged, [this]() {QTimer::singleShot(200, - this, - &ElementTextItemGroup::autoPos);} + this, + &ElementTextItemGroup::autoPos);} ); if(m_parent_element->diagram()) m_XrefChanged_timer = connect( @@ -326,8 +326,8 @@ void ElementTextItemGroup::setHoldToBottomPage(bool hold) &QETProject::XRefPropertiesChanged, [this]() {QTimer::singleShot(200, - this, - &ElementTextItemGroup::autoPos);} + this, + &ElementTextItemGroup::autoPos);} ); } autoPos(); @@ -438,6 +438,7 @@ QDomElement ElementTextItemGroup::toXml(QDomDocument &dom_document) const return dom_element; } +// TOOD: inherit from propertiesinterface /** @brief ElementTextItemGroup::fromXml Import data of this group from xml @@ -623,7 +624,7 @@ void ElementTextItemGroup::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if(diagram() && m_first_move) diagram()->elementTextsMover().beginMovement(diagram(), - this); + this); if(m_first_move) { @@ -706,7 +707,7 @@ void ElementTextItemGroup::mouseDoubleClickEvent( */ void ElementTextItemGroup::keyPressEvent(QKeyEvent *event) { - if(event->modifiers() == Qt::ControlModifier) + if(event->modifiers() == Qt::ControlModifier) { if(event->key() == Qt::Key_Left && m_alignment != Qt::AlignLeft) { @@ -800,12 +801,12 @@ void ElementTextItemGroup::updateXref() m_slave_Xref_item = new QGraphicsTextItem(xref_label, this); m_slave_Xref_item->setFont(QETApp::diagramTextsFont(5)); - m_update_slave_Xref_connection << connect(master_elmt, &Element::xChanged, this, &ElementTextItemGroup::updateXref); - m_update_slave_Xref_connection << connect(master_elmt, &Element::yChanged, this, &ElementTextItemGroup::updateXref); - m_update_slave_Xref_connection << connect(master_elmt, &Element::elementInfoChange, this, &ElementTextItemGroup::updateXref); - m_update_slave_Xref_connection << connect(project, &QETProject::projectDiagramsOrderChanged, this, &ElementTextItemGroup::updateXref); - m_update_slave_Xref_connection << connect(project, &QETProject::diagramRemoved, this, &ElementTextItemGroup::updateXref); - m_update_slave_Xref_connection << connect(project, &QETProject::XRefPropertiesChanged, this, &ElementTextItemGroup::updateXref); + m_update_slave_Xref_connection << connect(master_elmt, &Element::xChanged, this, &ElementTextItemGroup::updateXref); + m_update_slave_Xref_connection << connect(master_elmt, &Element::yChanged, this, &ElementTextItemGroup::updateXref); + m_update_slave_Xref_connection << connect(master_elmt, &Element::elementInfoChange, this, &ElementTextItemGroup::updateXref); + m_update_slave_Xref_connection << connect(project, &QETProject::projectDiagramsOrderChanged, this, &ElementTextItemGroup::updateXref); + m_update_slave_Xref_connection << connect(project, &QETProject::diagramRemoved, this, &ElementTextItemGroup::updateXref); + m_update_slave_Xref_connection << connect(project, &QETProject::XRefPropertiesChanged, this, &ElementTextItemGroup::updateXref); } else m_slave_Xref_item->setPlainText(xref_label); diff --git a/sources/qetgraphicsitem/elementtextitemgroup.h b/sources/qetgraphicsitem/elementtextitemgroup.h index e39397ab5..b8e25a213 100644 --- a/sources/qetgraphicsitem/elementtextitemgroup.h +++ b/sources/qetgraphicsitem/elementtextitemgroup.h @@ -32,7 +32,7 @@ class CrossRefItem; This class represent a group of element text Texts in the group can be aligned left / center /right */ -class ElementTextItemGroup : public QObject, public QGraphicsItemGroup +class ElementTextItemGroup : public QObject, public QGraphicsItemGroup // TODO: derive from PropertiesInterface { Q_OBJECT @@ -112,7 +112,7 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup m_hold_to_bottom_of_page = false, m_block_alignment_update = false, m_frame = false; - QPointF m_initial_position; + QPointF m_initial_position{QPointF(0,0)}; int m_vertical_adjustment = 0; CrossRefItem *m_Xref_item = nullptr; Element *m_parent_element = nullptr; diff --git a/sources/qetgraphicsitem/independenttextitem.cpp b/sources/qetgraphicsitem/independenttextitem.cpp index 0f9aee655..521c03bce 100644 --- a/sources/qetgraphicsitem/independenttextitem.cpp +++ b/sources/qetgraphicsitem/independenttextitem.cpp @@ -51,6 +51,7 @@ IndependentTextItem::~IndependentTextItem() { } +// TODO: inherit from PropertiesInterface /** Permet de lire le texte a mettre dans le champ a partir d'un element XML. Cette methode se base sur la position du champ pour assigner ou non la diff --git a/sources/qetgraphicsitem/independenttextitem.h b/sources/qetgraphicsitem/independenttextitem.h index cdf38b016..88d9e9d48 100644 --- a/sources/qetgraphicsitem/independenttextitem.h +++ b/sources/qetgraphicsitem/independenttextitem.h @@ -40,7 +40,7 @@ class IndependentTextItem : public DiagramTextItem int type() const override { return Type; } void fromXml(const QDomElement &) override; - QDomElement toXml(QDomDocument &) const override; + QDomElement toXml(QDomDocument&) const override; protected: void focusOutEvent(QFocusEvent *event) override; diff --git a/sources/qetgraphicsitem/qetgraphicsitem.cpp b/sources/qetgraphicsitem/qetgraphicsitem.cpp index e1c9bc6a0..c63d48870 100644 --- a/sources/qetgraphicsitem/qetgraphicsitem.cpp +++ b/sources/qetgraphicsitem/qetgraphicsitem.cpp @@ -25,10 +25,7 @@ @param parent : Parent Item */ QetGraphicsItem::QetGraphicsItem(QGraphicsItem *parent): - QGraphicsObject(parent), - is_movable_(true), - m_first_move(true), - snap_to_grid_(true) + QGraphicsObject(parent) {} QetGraphicsItem::~QetGraphicsItem() diff --git a/sources/qetgraphicsitem/qetgraphicsitem.h b/sources/qetgraphicsitem/qetgraphicsitem.h index 5c7742c35..7833d1a01 100644 --- a/sources/qetgraphicsitem/qetgraphicsitem.h +++ b/sources/qetgraphicsitem/qetgraphicsitem.h @@ -56,10 +56,10 @@ class QetGraphicsItem : public QGraphicsObject void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; protected: - bool is_movable_; - bool m_first_move; - bool snap_to_grid_; - QPointF m_mouse_to_origin_movement; + bool is_movable_{true}; + bool m_first_move{true}; + bool snap_to_grid_{true}; + QPointF m_mouse_to_origin_movement{QPointF(0,0)}; QET::GraphicsItemState m_state = QET:: GIOK; }; diff --git a/sources/qetgraphicsitem/qetshapeitem.cpp b/sources/qetgraphicsitem/qetshapeitem.cpp index f76d60f3f..30dc4a6a5 100644 --- a/sources/qetgraphicsitem/qetshapeitem.cpp +++ b/sources/qetgraphicsitem/qetshapeitem.cpp @@ -326,7 +326,7 @@ void QetShapeItem::paint( switch (m_shapeType) { - case Line: painter->drawLine(QLineF(m_P1, m_P2)); break; + case Line: painter->drawLine(QLineF(m_P1, m_P2)); break; case Rectangle: painter->drawRoundedRect(QRectF(m_P1, m_P2), m_xRadius, m_yRadius); break; @@ -663,7 +663,7 @@ void QetShapeItem::insertPoint() if(new_polygon != m_polygon) { //Wrap the undo for avoid to merge the undo commands when user add several points. - QUndoCommand *undo = new QUndoCommand(tr("Ajouter un point à un polygone")); + QUndoCommand *undo = new QUndoCommand(tr("Ajouter un point ?? un polygone")); new QPropertyUndoCommand(this, "polygon", m_polygon, new_polygon, undo); diagram()->undoStack().push(undo); } @@ -836,6 +836,7 @@ void QetShapeItem::handlerMouseReleaseEvent() } } +// TODO: inherit from Propertiesinterface! /** @brief QetShapeItem::fromXml Build this item from the xml description @@ -951,28 +952,28 @@ bool QetShapeItem::toDXF(const QString &filepath,const QPen &pen) switch (m_shapeType) { case Line: - Createdxf::drawLine(filepath, + Createdxf::drawLine(filepath, QLineF( mapToScene(m_P1), mapToScene(m_P2)), Createdxf::dxfColor(pen)); - return true; + return true; case Rectangle: - Createdxf::drawRectangle(filepath, + Createdxf::drawRectangle(filepath, QRectF(mapToScene(m_P1), mapToScene(m_P2)).normalized(), Createdxf::dxfColor(pen)); - return true; + return true; case Ellipse: - Createdxf::drawEllipse(filepath, + Createdxf::drawEllipse(filepath, QRectF(mapToScene(m_P1), mapToScene(m_P2)).normalized(), Createdxf::dxfColor(pen)); - return true; + return true; case Polygon: - Createdxf::drawPolygon(filepath,m_polygon,Createdxf::dxfColor(pen)); - return true; + Createdxf::drawPolygon(filepath,m_polygon,Createdxf::dxfColor(pen)); + return true; default: - return false; + return false; } } @@ -995,10 +996,10 @@ void QetShapeItem::editProperty() QString QetShapeItem::name() const { switch (m_shapeType) { - case Line: return tr("une ligne"); + case Line: return tr("une ligne"); case Rectangle: return tr("un rectangle"); - case Ellipse: return tr("une éllipse"); + case Ellipse: return tr("une ??llipse"); case Polygon: return tr("une polyligne"); - default: return tr("une shape"); + default: return tr("une shape"); } } diff --git a/sources/qetgraphicsitem/slaveelement.h b/sources/qetgraphicsitem/slaveelement.h index 47a123d28..c51e20555 100644 --- a/sources/qetgraphicsitem/slaveelement.h +++ b/sources/qetgraphicsitem/slaveelement.h @@ -35,7 +35,7 @@ class SlaveElement : public Element void unlinkElement(Element *elmt) override; private: - QGraphicsTextItem *m_xref_item; + QGraphicsTextItem *m_xref_item{nullptr}; }; #endif // SLAVEELEMENT_H diff --git a/sources/qetgraphicsitem/terminal.cpp b/sources/qetgraphicsitem/terminal.cpp index 8efe08b34..df85d4baa 100644 --- a/sources/qetgraphicsitem/terminal.cpp +++ b/sources/qetgraphicsitem/terminal.cpp @@ -25,6 +25,8 @@ #include "../qetgraphicsitem/element.h" #include "conductortextitem.h" +#include "../qetxml.h" + #include QColor Terminal::neutralColor = QColor(Qt::blue); @@ -41,7 +43,7 @@ const qreal Terminal::Z = 1000; @param name of terminal @param hiddenName */ -void Terminal::init() +void Terminal::init(QString number, QString name, bool hiddenName) { //Calcul the docking point of the element //m_pos of d is the docking point of conductor @@ -62,7 +64,13 @@ void Terminal::init() origin += QPointF(-3.0, -3.0); qreal w = qAbs(dcx - dex) + 7; qreal h = qAbs(dcy - dey) + 7; - m_br = QRectF(origin, QSizeF(w, h)); + m_br = QRectF(origin, QSizeF(w, h)); + + // Number of terminal + number_terminal_ = std::move(number); + // Name of terminal + d->m_name = std::move(name); + name_terminal_hidden = hiddenName; setAcceptHoverEvents(true); setAcceptedMouseButtons(Qt::LeftButton); @@ -70,13 +78,92 @@ void Terminal::init() setZValue(Z); } +/*! + \brief Terminal::init + Additionaly to the init above, this method stores position and orientation into the data class + \param pf + \param o + \param number + \param name + \param hiddenName +*/ +void Terminal::init( + QPointF pf, + Qet::Orientation o, + QString number, + QString name, + bool hiddenName) +{ + setTagName("terminal"); + // definition du pount d'amarrage pour un conducteur + d->m_pos = pf; + + // definition de l'orientation de la borne (par defaut : sud) + if (o < Qet::North || o > Qet::West) d->m_orientation = Qet::South; + else d->m_orientation = o; + + init(number, name, hiddenName); +} + +/** + initialise une borne + @param pf position du point d'amarrage pour un conducteur + @param o orientation de la borne : Qt::Horizontal ou Qt::Vertical + @param e Element auquel cette borne appartient +*/ +Terminal::Terminal(QPointF pf, Qet::Orientation o, Element *e) : + QGraphicsObject(e), + d(new TerminalData(this)), + parent_element_ (e) +{ + init(pf, o, "_", "_", false); +} + +/** + initialise une borne + @param pf_x Abscisse du point d'amarrage pour un conducteur + @param pf_y Ordonnee du point d'amarrage pour un conducteur + @param o orientation de la borne : Qt::Horizontal ou Qt::Vertical + @param e Element auquel cette borne appartient +*/ +Terminal::Terminal(qreal pf_x, qreal pf_y, Qet::Orientation o, Element *e) : + QGraphicsObject(e), + d(new TerminalData(this)), + parent_element_ (e) +{ + init(QPointF(pf_x, pf_y), o, "_", "_", false); +} + +/** + initialise une borne + @param pf position du point d'amarrage pour un conducteur + @param o orientation de la borne : Qt::Horizontal ou Qt::Vertical + @param num number of terminal (ex 3 - 4 for NO) + @param name of terminal + @param hiddenName hide or show the name + @param e Element auquel cette borne appartient +*/ +Terminal::Terminal( + QPointF pf, + Qet::Orientation o, + QString num, + QString name, + bool hiddenName, + Element *e) : + QGraphicsObject (e), + d(new TerminalData(this)), + parent_element_ (e) +{ + init(pf, o, std::move(num), std::move(name), hiddenName); +} + Terminal::Terminal(TerminalData* data, Element* e) : QGraphicsObject(e), d(data), parent_element_(e) { d->setParent(this); - init(); + init("_", "_", false); } /** @@ -84,7 +171,7 @@ Terminal::Terminal(TerminalData* data, Element* e) : * Destruction of the terminal, and also docked conductor */ Terminal::~Terminal() { - qDeleteAll(m_conductors_list); + qDeleteAll(m_conductors_list); } /** @@ -110,6 +197,34 @@ Qet::Orientation Terminal::orientation() const } else return(d->m_orientation); } +/** + @brief Terminal::setNumber + @param number +*/ +void Terminal::setNumber(QString number) +{ + number_terminal_ = std::move(number); +} + +/** + @brief Terminal::setName + @param name : QString + @param hiddenName : bool +*/ +void Terminal::setName(QString name, bool hiddenName) +{ + d->m_name = std::move(name); + name_terminal_hidden = hiddenName; +} + +/** + @brief Terminal::name + @return the name of terminal. +*/ +inline QString Terminal::name() const { + return(d->m_name); +} + /** @brief Terminal::addConductor Add a conductor to this terminal @@ -175,8 +290,8 @@ void Terminal::paint( painter -> save(); //annulation des renderhints - painter -> setRenderHint(QPainter::Antialiasing, false); - painter -> setRenderHint(QPainter::TextAntialiasing, false); + painter -> setRenderHint(QPainter::Antialiasing, false); + painter -> setRenderHint(QPainter::TextAntialiasing, false); painter -> setRenderHint(QPainter::SmoothPixmapTransform, false); // on travaille avec les coordonnees de l'element parent @@ -310,7 +425,7 @@ void Terminal::drawHelpLine(bool draw) QLineF Terminal::HelpLine() const { QPointF scene_dock = dockConductor(); - QRectF rect = diagram() -> border_and_titleblock.insideBorderRect(); + QRectF rect = diagram() -> border_and_titleblock.insideBorderRect(); QLineF line(scene_dock , QPointF()); @@ -388,7 +503,7 @@ Terminal* Terminal::alignedWithTerminal() const //Available_terminals have several terminals, we get the nearest terminal line.setP2(available_terminals.first() -> dockConductor()); - qreal current_lenght = line.length(); + qreal current_lenght = line.length(); Terminal *nearest_terminal = available_terminals.takeFirst(); //Search the nearest terminal to this one @@ -457,7 +572,7 @@ void Terminal::mouseMoveEvent(QGraphicsSceneMouseEvent *e) //setCursor(Qt::CrossCursor); // d'un mouvement a l'autre, il faut retirer l'effet hover de la borne precedente - if (m_previous_terminal) { + if (m_previous_terminal) { if (m_previous_terminal == this) m_hovered = true; else m_previous_terminal -> m_hovered = false; m_previous_terminal -> m_hovered_color = m_previous_terminal -> neutralColor; @@ -624,6 +739,10 @@ bool Terminal::canBeLinkedTo(Terminal *other_terminal) return true; } +void Terminal::setID(int id) { + m_id = id; +} + /** @brief Terminal::conductors @return La liste des conducteurs lies a cette borne @@ -634,22 +753,19 @@ QList Terminal::conductors() const } /** - @brief Terminal::toXml + @brief Terminal::toXmlPriv Methode d'export en XML @param doc Le Document XML a utiliser pour creer l'element XML @return un QDomElement representant cette borne */ -QDomElement Terminal::toXml(QDomDocument &doc) const +void Terminal::toXmlPriv(QDomElement &qdo) const { - QDomElement qdo = doc.createElement("terminal"); + // for backward compatibility + qdo.setAttribute("x", QString("%1").arg(dock_elmt_.x())); + qdo.setAttribute("y", QString("%1").arg(dock_elmt_.y())); + // end for backward compatibility - // for backward compatibility - qdo.setAttribute("x", QString("%1").arg(dock_elmt_.x())); - qdo.setAttribute("y", QString("%1").arg(dock_elmt_.y())); - // end for backward compatibility - - qdo.setAttribute("orientation", d->m_orientation); - return(qdo); + qdo.setAttribute("orientation", d->m_orientation); } /** @@ -658,42 +774,25 @@ QDomElement Terminal::toXml(QDomDocument &doc) const @param terminal Le QDomElement a analyser @return true si le QDomElement passe en parametre est une borne, false sinon */ -bool Terminal::valideXml(QDomElement &terminal) +bool Terminal::valideXml(const QDomElement &terminal) { - // verifie le nom du tag if (terminal.tagName() != "terminal") return(false); - // verifie la presence des attributs minimaux - if (!terminal.hasAttribute("x")) return(false); - if (!terminal.hasAttribute("y")) return(false); - if (!terminal.hasAttribute("orientation")) return(false); +// affuteuse_250h.qet contains in line 8398 terminals which do not have this +// if (QETXML::propertyString(terminal, "number")) +// return false; +// affuteuse_250h.qet contains in line 8398 terminals which do not have this +// if (QETXML::propertyBool(terminal, "nameHidden")) +// return false; - bool conv_ok; - // parse l'abscisse - terminal.attribute("x").toDouble(&conv_ok); - if (!conv_ok) return(false); - - // parse l'ordonnee - terminal.attribute("y").toDouble(&conv_ok); - if (!conv_ok) return(false); - - // parse l'id - terminal.attribute("id").toInt(&conv_ok); - if (!conv_ok) return(false); - - // parse l'orientation - int terminal_or = terminal.attribute("orientation").toInt(&conv_ok); - if (!conv_ok) return(false); - if (terminal_or != Qet::North - && terminal_or != Qet::South - && terminal_or != Qet::East - && terminal_or != Qet::West) return(false); + if (!TerminalData::valideXml(terminal)) + return false; // a ce stade, la borne est syntaxiquement correcte - return(true); + return true; } -/** +/** RETURNS True @brief Terminal::fromXml Permet de savoir si un element XML represente cette borne. Attention, l'element XML n'est pas verifie @@ -701,13 +800,17 @@ bool Terminal::valideXml(QDomElement &terminal) @return true si la borne "se reconnait" (memes coordonnes, meme orientation), false sinon */ -bool Terminal::fromXml(QDomElement &terminal) -{ - return ( - qFuzzyCompare(terminal.attribute("x").toDouble(), dock_elmt_.x()) && - qFuzzyCompare(terminal.attribute("y").toDouble(), dock_elmt_.y()) && - (terminal.attribute("orientation").toInt() == d->m_orientation) - ); +bool Terminal::fromXmlPriv(const QDomElement &terminal) { + QETXML::propertyString(terminal, "number", &number_terminal_); + + QETXML::propertyBool(terminal, "nameHidden", &name_terminal_hidden); + + if(!d->fromXml(terminal)) + return false; + + + init(number_terminal_, d->m_name, name_terminal_hidden); // initialize dock_elmt_. This must be done after Terminal data is initialized + return true; } /** @@ -744,6 +847,18 @@ QUuid Terminal::uuid() const return d->m_uuid; } +int Terminal::ID() const { + return m_id; +} + +QPointF Terminal::dockPos() { + return dock_elmt_; +} + +QPointF Terminal::originPos() { + return d->m_pos; +} + /** @brief Conductor::relatedPotentialTerminal Return terminal at the same potential from the same diff --git a/sources/qetgraphicsitem/terminal.h b/sources/qetgraphicsitem/terminal.h index 8977a73eb..3339266a0 100644 --- a/sources/qetgraphicsitem/terminal.h +++ b/sources/qetgraphicsitem/terminal.h @@ -21,6 +21,9 @@ #include #include +#include "../qet.h" +#include "../properties/propertiesinterface.h" + class Conductor; class Diagram; class Element; @@ -32,7 +35,7 @@ class TerminalData; plug point for conductors. This class handles all mouse events for connecting conductors */ -class Terminal : public QGraphicsObject +class Terminal : public QGraphicsObject, public PropertiesInterface { Q_OBJECT @@ -42,7 +45,11 @@ class Terminal : public QGraphicsObject // constructors, destructor public: + Terminal(QPointF, Qet::Orientation, Element * = nullptr); + Terminal(qreal, qreal, Qet::Orientation, Element * = nullptr); Terminal(TerminalData* data, Element *e = nullptr); + Terminal(QPointF, Qet::Orientation, QString number, + QString name, bool hiddenName, Element * = nullptr); ~Terminal() override; private: @@ -63,17 +70,25 @@ class Terminal : public QGraphicsObject const QStyleOptionGraphicsItem *, QWidget *) override; void drawHelpLine (bool draw = true); - QLineF HelpLine () const; + QLineF HelpLine () const; QRectF boundingRect () const override; // methods to manage conductors attached to the terminal Terminal* alignedWithTerminal () const; - bool addConductor (Conductor *conductor); - void removeConductor (Conductor *conductor); - int conductorsCount () const; - Diagram *diagram () const; - Element *parentElement () const; - QUuid uuid () const; + bool addConductor (Conductor *conductor); + void removeConductor (Conductor *conductor); + int conductorsCount () const; + Diagram *diagram () const; + Element *parentElement () const; + QUuid uuid () const; + int ID() const; + QPointF dockPos(); + QPointF originPos(); + QString number() const; + void setNumber(QString number); + void setName(QString name, bool hiddenName); + QString name() const; + QList conductors() const; Qet::Orientation orientation() const; @@ -81,11 +96,15 @@ class Terminal : public QGraphicsObject void updateConductor(); bool isLinkedTo(Terminal *); bool canBeLinkedTo(Terminal *); + void setID(int id); // methods related to XML import/export - static bool valideXml(QDomElement &); - bool fromXml (QDomElement &); - QDomElement toXml (QDomDocument &) const; + static bool valideXml(const QDomElement &); + bool fromXmlPriv (const QDomElement &) override; + void toXmlPriv(QDomElement &) const override; + + void toSettings(QSettings &,const QString & = QString()) const override {/*TODO: implement*/} + void fromSettings(QSettings &,const QString & = QString()) override{/*TODO: implement*/} protected: // methods related to events management @@ -103,6 +122,7 @@ class Terminal : public QGraphicsObject static const qreal terminalSize; static const qreal Z; // Various static colors used for hover effects + // The assignement is in the cpp file /// default color static QColor neutralColor; /// color for legal actions @@ -113,12 +133,12 @@ class Terminal : public QGraphicsObject static QColor forbiddenColor; private: - bool m_draw_help_line{false}; + bool m_draw_help_line{false}; QGraphicsLineItem *m_help_line{nullptr}; QGraphicsLineItem *m_help_line_a{nullptr}; - TerminalData* d; + TerminalData* d{nullptr}; /// Parent electrical element Element *parent_element_{nullptr}; @@ -127,18 +147,29 @@ class Terminal : public QGraphicsObject QPointF dock_elmt_; private: /// List of conductors attached to the terminal - QList m_conductors_list; - QRectF m_br; - /// Last terminal seen through an attached conductor - Terminal *m_previous_terminal = nullptr; - /// Whether the mouse pointer is hovering the terminal - bool m_hovered = false; - /// Color used for the hover effect - QColor m_hovered_color = Terminal::neutralColor; + QList m_conductors_list; + /** + Pointer to a rectangle representing the terminal bounding rect; + used to calculate the bounding rect once only; + used a pointer because boundingRect() is supposed to be const. + */ + QRectF m_br; + /// Last terminal seen through an attached conductor + Terminal *m_previous_terminal{nullptr}; + /// Whether the mouse pointer is hovering the terminal + bool m_hovered{false}; + /// Color used for the hover effect + QColor m_hovered_color{Terminal::neutralColor}; + /// Number of Terminal + QString number_terminal_; + bool name_terminal_hidden{true}; + + /// legacy id used by the conductor to find the terminal. From 0.8x on the uuid is used instead. + int m_id{-1}; private: - void init(); - void init(QPointF pf, Qet::Orientation o); + void init(QString number, QString name, bool hiddenName); + void init(QPointF pf, Qet::Orientation o,QString number, QString name, bool hiddenName); }; /** @@ -147,9 +178,19 @@ class Terminal : public QGraphicsObject */ inline int Terminal::conductorsCount() const { - return(m_conductors_list.size()); + return(m_conductors_list.size()); } +/** + @brief Terminal::number + @return the number of terminal. +*/ +inline QString Terminal::number() const +{ + return(number_terminal_); +} + + QList relatedPotentialTerminal (const Terminal *terminal, const bool all_diagram = true); diff --git a/sources/qetproject.cpp b/sources/qetproject.cpp index b4f16b8a4..a75b7a7b7 100644 --- a/sources/qetproject.cpp +++ b/sources/qetproject.cpp @@ -39,6 +39,8 @@ #include #include +#include "qetxml.h" + static int BACKUP_INTERVAL = 120000; //interval in ms of backup = 2min /** @@ -47,7 +49,7 @@ static int BACKUP_INTERVAL = 120000; //interval in ms of backup = 2min @param parent */ QETProject::QETProject(QObject *parent) : - QObject (parent), + QObject (parent), m_titleblocks_collection(this), m_data_base(this, this) { @@ -64,7 +66,7 @@ QETProject::QETProject(QObject *parent) : @param parent : parent QObject */ QETProject::QETProject(const QString &path, QObject *parent) : - QObject (parent), + QObject (parent), m_titleblocks_collection(this), m_data_base(this, this) { @@ -85,7 +87,7 @@ QETProject::QETProject(const QString &path, QObject *parent) : @param parent : parent QObject */ QETProject::QETProject(KAutoSaveFile *backup, QObject *parent) : - QObject (parent), + QObject (parent), m_titleblocks_collection(this), m_data_base(this, this) { @@ -1489,11 +1491,11 @@ void QETProject::readDefaultPropertiesXml(QDomDocument &xml_project) QDomElement newdiagrams_elmt = newdiagrams_nodes.at(0).toElement(); // By default, use value find in the global conf of QElectroTech - default_border_properties_ = BorderProperties:: defaultProperties(); + default_border_properties_ = BorderProperties:: defaultProperties(); default_titleblock_properties_ = TitleBlockProperties::defaultProperties(); default_conductor_properties_ = ConductorProperties:: defaultProperties(); - m_default_report_properties = ReportProperties:: defaultProperties(); - m_default_xref_properties = XRefProperties:: defaultProperties(); + m_default_report_properties = ReportProperties:: defaultProperties(); + m_default_xref_properties = XRefProperties:: defaultProperties(); //Read values indicate in project QDomElement border_elmt, titleblock_elmt, conductors_elmt, report_elmt, xref_elmt, conds_autonums, folio_autonums, element_autonums; @@ -1532,7 +1534,11 @@ void QETProject::readDefaultPropertiesXml(QDomDocument &xml_project) { XRefProperties xrp; xrp.fromXml(elmt); - m_default_xref_properties.insert(elmt.attribute("type"), xrp); + QString type; + if (QETXML::propertyString(elmt, "type", &type) == QETXML::PropertyFlags::Success) + m_default_xref_properties.insert(type, xrp); + else + qDebug() << "xref Property was not added to m_default_xref_properties."; } } if (!conds_autonums.isNull()) @@ -1590,19 +1596,13 @@ void QETProject::writeDefaultPropertiesXml(QDomElement &xml_element) QDomDocument xml_document = xml_element.ownerDocument(); // export size of border - QDomElement border_elmt = xml_document.createElement("border"); - default_border_properties_.toXml(border_elmt); - xml_element.appendChild(border_elmt); + xml_element.appendChild(default_border_properties_.toXml(xml_document)); // export content of titleblock - QDomElement titleblock_elmt = xml_document.createElement("inset"); - default_titleblock_properties_.toXml(titleblock_elmt); - xml_element.appendChild(titleblock_elmt); + xml_element.appendChild(default_titleblock_properties_.toXml(xml_document)); // exporte default conductor - QDomElement conductor_elmt = xml_document.createElement("conductors"); - default_conductor_properties_.toXml(conductor_elmt); - xml_element.appendChild(conductor_elmt); + xml_element.appendChild(default_conductor_properties_.toXml(xml_document)); // export default report properties QDomElement report_elmt = xml_document.createElement("report"); @@ -1828,8 +1828,8 @@ void QETProject::setProjectProperties(const DiagramContext &context) { bool QETProject::projectWasModified() { - if ( projectOptionsWereModified() || - !m_undo_stack -> isClean() || + if ( projectOptionsWereModified() || + !m_undo_stack -> isClean() || m_titleblocks_collection.templates().count() ) return(true); 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 diff --git a/sources/titleblock/helpercell.h b/sources/titleblock/helpercell.h index 8e447f7bc..c72b02678 100644 --- a/sources/titleblock/helpercell.h +++ b/sources/titleblock/helpercell.h @@ -38,11 +38,11 @@ class HelperCell : public QGraphicsObject, public QGraphicsLayoutItem { // attributes public: - QColor background_color; ///< Background color when rendering this cell - QColor foreground_color; ///< Text color when rendering this cell - QString label; ///< Label displayed in this cell - Qt::Orientation orientation; ///< Orientation of this cell - int index; ///< Index of this cell + QColor background_color{Qt::white}; ///< Background color when rendering this cell + QColor foreground_color{Qt::black}; ///< Text color when rendering this cell + QString label; ///< Label displayed in this cell + Qt::Orientation orientation{Qt::Horizontal}; ///< Orientation of this cell + int index{-1}; ///< Index of this cell // methods public: diff --git a/sources/titleblock/splittedhelpercell.h b/sources/titleblock/splittedhelpercell.h index a8f198fbf..65808b7f6 100644 --- a/sources/titleblock/splittedhelpercell.h +++ b/sources/titleblock/splittedhelpercell.h @@ -36,10 +36,11 @@ class SplittedHelperCell : public HelperCell { void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = nullptr) override; // attributes + // colors are set in the constructor QColor split_background_color; ///< Background color on the split side QColor split_foreground_color; ///< Text color on the split side - QString split_label; ///< Text displayed on the split side - int split_size; ///< Length of the split side + QString split_label; ///< Text displayed on the split side + int split_size; ///< Length of the split side }; #endif diff --git a/sources/titleblockproperties.cpp b/sources/titleblockproperties.cpp index 4bb6b688b..69b321c7a 100644 --- a/sources/titleblockproperties.cpp +++ b/sources/titleblockproperties.cpp @@ -19,16 +19,15 @@ #include "qet.h" #include "qetapp.h" +#include "qetxml.h" + /** Constructeur. Initialise un objet TitleBlockProperties avec tous les champs vides (date vide + useDate a UseDateValue). */ -TitleBlockProperties::TitleBlockProperties() : - date(), - useDate(UseDateValue), - display_at(Qt::BottomEdge), - collection (QET::QetCollection::Common) +TitleBlockProperties::TitleBlockProperties() { + setTagName("titleblock"); } /** @@ -69,60 +68,65 @@ bool TitleBlockProperties::operator!=(const TitleBlockProperties &ip) { return(!(*this == ip)); } - /** - Exporte le cartouche sous formes d'attributs XML ajoutes a l'element e. - @param e Element XML auquel seront ajoutes des attributs + Exporte le cartouche sous formes d'attributs XML ajoutes a l'element e. + @param e Element XML auquel seront ajoutes des attributs */ -void TitleBlockProperties::toXml(QDomElement &e) const -{ - e.setAttribute("author", author); - e.setAttribute("title", title); - e.setAttribute("filename", filename); - e.setAttribute("plant", plant); - e.setAttribute("locmach", locmach); - e.setAttribute("indexrev",indexrev); - e.setAttribute("version", version); - e.setAttribute("folio", folio); - e.setAttribute("auto_page_num", auto_page_num); - e.setAttribute("date", exportDate()); - e.setAttribute("displayAt", (display_at == Qt::BottomEdge? "bottom" : "right")); - if (!template_name.isEmpty()) - { - e.setAttribute("titleblocktemplate", template_name); - e.setAttribute("titleblocktemplateCollection", QET::qetCollectionToString(collection)); - } - - if (context.keys().count()) { - QDomElement properties = e.ownerDocument().createElement("properties"); - context.toXml(properties); - e.appendChild(properties); - } +void TitleBlockProperties::toXmlPriv(QDomElement& e) const { + e.setAttribute("author", author); + e.setAttribute("title", title); + e.setAttribute("filename", filename); + e.setAttribute("plant", plant); + e.setAttribute("locmach", locmach); + e.setAttribute("indexrev",indexrev); + e.setAttribute("version", version); + e.setAttribute("folio", folio); + e.setAttribute("auto_page_num", auto_page_num); + e.setAttribute("date", exportDate()); + e.setAttribute("displayAt", (display_at == Qt::BottomEdge? "bottom" : "right")); + if (!template_name.isEmpty()) + { + e.setAttribute("titleblocktemplate", template_name); + e.setAttribute("titleblocktemplateCollection", QET::qetCollectionToString(collection)); + } + + if (context.keys().count()) { + QDomElement properties = e.ownerDocument().createElement("properties"); + context.toXml(properties); + e.appendChild(properties); + } } -/** +/** RETURNS True Importe le cartouche a partir des attributs XML de l'element e @param e Element XML dont les attributs seront lus */ -void TitleBlockProperties::fromXml(const QDomElement &e) { +bool TitleBlockProperties::fromXmlPriv(const QDomElement &e) { + + // reads the historical fields - if (e.hasAttribute("author")) author = e.attribute("author"); - if (e.hasAttribute("title")) title = e.attribute("title"); - if (e.hasAttribute("filename")) filename = e.attribute("filename"); - if (e.hasAttribute("plant")) plant = e.attribute("plant"); - if (e.hasAttribute("locmach")) locmach = e.attribute("locmach"); - if (e.hasAttribute("indexrev")) indexrev = e.attribute("indexrev"); - if (e.hasAttribute("version")) version = e.attribute("version"); - if (e.hasAttribute("folio")) folio = e.attribute("folio"); - if (e.hasAttribute("auto_page_num")) auto_page_num = e.attribute("auto_page_num"); - if (e.hasAttribute("date")) setDateFromString(e.attribute("date")); - if (e.hasAttribute("displayAt")) display_at = (e.attribute("displayAt") == "bottom" ? Qt::BottomEdge : Qt::RightEdge); + QETXML::propertyString(e, "author", &author); + QETXML::propertyString(e, "title", &title); + QETXML::propertyString(e, "filename", &filename); + QETXML::propertyString(e, "plant", &plant); + QETXML::propertyString(e, "locmach", &locmach); + QETXML::propertyString(e, "indexrev", &indexrev); + QETXML::propertyString(e, "version", &version); + QETXML::propertyString(e, "folio", &folio); + QETXML::propertyString(e, "auto_page_num", &auto_page_num); + QString date; + QETXML::propertyString(e, "date", &date); + setDateFromString(date); + + QString display_at_temp; + if (QETXML::propertyString(e, "displayAt", &display_at_temp) == QETXML::PropertyFlags::Success) + display_at = (display_at_temp == "bottom" ? Qt::BottomEdge : Qt::RightEdge); // otherwise it gets default in header file // reads the template used to render the title block - if (e.hasAttribute("titleblocktemplate")) - { - template_name = e.attribute("titleblocktemplate"); - collection = QET::qetCollectionFromString(e.attribute("titleblocktemplateCollection")); + if (QETXML::propertyString(e, "titleblocktemplate", &template_name) == QETXML::PropertyFlags::Success) { + QString tbc; + if (QETXML::propertyString(e, "titleblocktemplateCollection", &tbc) == QETXML::PropertyFlags::Success) + collection = QET::qetCollectionFromString(tbc); } // reads the additional fields used to fill the title block @@ -130,6 +134,7 @@ void TitleBlockProperties::fromXml(const QDomElement &e) { foreach (QDomElement e, QET::findInDomElement(e, "properties")) { context.fromXml(e); } + return true; } /** @@ -140,16 +145,16 @@ void TitleBlockProperties::fromXml(const QDomElement &e) { */ void TitleBlockProperties::toSettings(QSettings &settings, const QString &prefix) const { - settings.setValue(prefix + "title", title); + settings.setValue(prefix + "title", title); settings.setValue(prefix + "author", author); settings.setValue(prefix + "filename", filename); settings.setValue(prefix + "plant", plant); settings.setValue(prefix + "locmach", locmach); settings.setValue(prefix + "indexrev", indexrev); settings.setValue(prefix + "version", version); - settings.setValue(prefix + "folio", folio); - settings.setValue(prefix + "auto_page_num", auto_page_num); - settings.setValue(prefix + "date", exportDate()); + settings.setValue(prefix + "folio", folio); + settings.setValue(prefix + "auto_page_num", auto_page_num); + settings.setValue(prefix + "date", exportDate()); settings.setValue(prefix + "displayAt", (display_at == Qt::BottomEdge? "bottom" : "right")); settings.setValue(prefix + "titleblocktemplate", template_name.isEmpty()? QString() : template_name); settings.setValue(prefix + "titleblocktemplateCollection", QET::qetCollectionToString(collection)); @@ -162,14 +167,14 @@ void TitleBlockProperties::toSettings(QSettings &settings, const QString &prefix @param prefix prefixe a ajouter devant les noms des parametres */ void TitleBlockProperties::fromSettings(QSettings &settings, const QString &prefix) { - title = settings.value(prefix + "title").toString(); + title = settings.value(prefix + "title").toString(); author = settings.value(prefix + "author").toString(); filename = settings.value(prefix + "filename").toString(); - plant = settings.value(prefix + "plant").toString(); + plant = settings.value(prefix + "plant").toString(); locmach = settings.value(prefix + "locmach").toString(); indexrev = settings.value(prefix + "indexrev").toString(); version = settings.value(prefix + "version").toString(); - folio = settings.value(prefix + "folio", "%id/%total").toString(); + folio = settings.value(prefix + "folio", "%id/%total").toString(); auto_page_num = settings.value(prefix + "auto_page_num").toString(); setDateFromString(settings.value(prefix + "date").toString()); display_at = (settings.value(prefix + "displayAt", QVariant("bottom")).toString() == "bottom" ? Qt::BottomEdge : Qt::RightEdge); diff --git a/sources/titleblockproperties.h b/sources/titleblockproperties.h index a3593603b..eafd5dc6e 100644 --- a/sources/titleblockproperties.h +++ b/sources/titleblockproperties.h @@ -21,12 +21,14 @@ #include "diagramcontext.h" #include "qet.h" +#include "properties/propertiesinterface.h" + /** This class provides a container for the properties of a particular title block, i.e. title, author, date, filename, folio, template, custom properties, ... */ -class TitleBlockProperties { +class TitleBlockProperties: public PropertiesInterface { public: TitleBlockProperties(); virtual ~TitleBlockProperties(); @@ -39,10 +41,10 @@ class TitleBlockProperties { bool operator==(const TitleBlockProperties &); bool operator!=(const TitleBlockProperties &); - void toXml(QDomElement &) const; - void fromXml(const QDomElement &); - void toSettings(QSettings &, const QString & = QString()) const; - void fromSettings(QSettings &, const QString & = QString()); + void toXmlPriv(QDomElement &e) const override; + bool fromXmlPriv(const QDomElement &) override; + void toSettings(QSettings &, const QString & = QString()) const override; + void fromSettings(QSettings &, const QString & = QString()) override; void setAutoPageNum(QString autonum) {auto_page_num = autonum;} @@ -51,21 +53,21 @@ class TitleBlockProperties { QDate finalDate() const ; // attributes - QString title; ///< Folio title (displayed by the default template) - QString author; ///< Author of the diagram/folio (displayed by the default template) - QDate date; ///< Date (displayed by the default template) - QString filename; ///< Filename (displayed by the default template) - QString plant; ///< Plant (displayed by the default template) - QString locmach; ///< Location(displayed by the default template) - QString indexrev; ///< Revision Index (displayed by the default template) - QString version; ///< Version (displayed by the default template) - QString folio; ///< Folio information (displayed by the default template) + QString title; ///< Folio title (displayed by the default template) + QString author; ///< Author of the diagram/folio (displayed by the default template) + QDate date; ///< Date (displayed by the default template) + QString filename; ///< Filename (displayed by the default template) + QString plant; ///< Plant (displayed by the default template) + QString locmach; ///< Location(displayed by the default template) + QString indexrev; ///< Revision Index (displayed by the default template) + QString version; ///< Version (displayed by the default template) + QString folio; ///< Folio information (displayed by the default template) QString auto_page_num; - DateManagement useDate; ///< Wheter to use the date attribute - QString template_name; ///< Name of the template used to render the title block - an empty string means "the default template provided by the application" + DateManagement useDate{UseDateValue}; ///< Wheter to use the date attribute + QString template_name; ///< Name of the template used to render the title block - an empty string means "the default template provided by the application" DiagramContext context; ///< Container for the additional, user-defined fields - Qt::Edge display_at; ///< Edge to display the titleblock - QET::QetCollection collection; ///