From f54bea713e5198f5060b4c3b991b94d09fbf7575 Mon Sep 17 00:00:00 2001 From: joshua Date: Wed, 21 Dec 2022 19:18:49 +0100 Subject: [PATCH] Terminal strip item can saved / loaded to .qet file --- qelectrotech.pro | 6 +- .../GraphicsItem/terminalstripdrawer.cpp | 5 + .../GraphicsItem/terminalstripdrawer.h | 5 +- .../GraphicsItem/terminalstripitem.cpp | 45 +++++- .../GraphicsItem/terminalstripitem.h | 10 ++ sources/diagram.cpp | 38 ++++- sources/qetproject.cpp | 43 ++++-- sources/qetproject.h | 1 + sources/qetxml.cpp | 35 ++++- sources/qetxml.h | 5 + sources/xml/terminalstripitemxml.cpp | 131 ++++++++++++++++++ sources/xml/terminalstripitemxml.h | 37 +++++ 12 files changed, 334 insertions(+), 27 deletions(-) create mode 100644 sources/xml/terminalstripitemxml.cpp create mode 100644 sources/xml/terminalstripitemxml.h diff --git a/qelectrotech.pro b/qelectrotech.pro index e8d97d08d..c0c050ff8 100644 --- a/qelectrotech.pro +++ b/qelectrotech.pro @@ -164,7 +164,8 @@ HEADERS += $$files(sources/*.h) $$files(sources/ui/*.h) \ $$files(sources/TerminalStrip/*.h) \ $$files(sources/TerminalStrip/ui/*.h) \ $$files(sources/TerminalStrip/UndoCommand/*.h) \ - $$files(sources/TerminalStrip/GraphicsItem/*.h) + $$files(sources/TerminalStrip/GraphicsItem/*.h) \ + $$files(sources/xml/*.h) SOURCES += $$files(sources/*.cpp) \ $$files(sources/editor/*.cpp) \ @@ -201,7 +202,8 @@ SOURCES += $$files(sources/*.cpp) \ $$files(sources/TerminalStrip/*.cpp) \ $$files(sources/TerminalStrip/ui/*.cpp) \ $$files(sources/TerminalStrip/UndoCommand/*.cpp) \ - $$files(sources/TerminalStrip/GraphicsItem/*.cpp) + $$files(sources/TerminalStrip/GraphicsItem/*.cpp) \ + $$files(sources/xml/*.cpp) # Needed for use promote QTreeWidget in terminalstripeditor.ui INCLUDEPATH += sources/TerminalStrip/ui diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp index b1c011c09..f25e7d43e 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp +++ b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp @@ -32,6 +32,11 @@ TerminalStripDrawer::TerminalStripDrawer(QPointer strip) : m_strip(strip) {} +void TerminalStripDrawer::setStrip(TerminalStrip *strip) +{ + m_strip = strip; +} + /** * @brief TerminalStripDrawer::paint * @param painter diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h index a7f3a4c11..22a12349a 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h +++ b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h @@ -27,9 +27,10 @@ class TerminalStrip; class TerminalStripDrawer { public: - TerminalStripDrawer(QPointer strip); - void paint(QPainter *painter); + TerminalStripDrawer(QPointer strip = QPointer()); + void setStrip(TerminalStrip *strip); + void paint(QPainter *painter); QRectF boundingRect() const; private: diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp b/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp index 86427d307..6cbdcdb52 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp +++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp @@ -16,6 +16,8 @@ along with QElectroTech. If not, see . */ #include "terminalstripitem.h" + +#include "../diagram.h" #include "../../qetgraphicsitem/qgraphicsitemutility.h" #include "../terminalstrip.h" #include "../ui/terminalstripeditorwindow.h" @@ -26,7 +28,29 @@ TerminalStripItem::TerminalStripItem(QPointer strip, QGraphicsIte m_drawer{strip} { setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); - setAcceptHoverEvents(true); + setAcceptHoverEvents(true); +} + +TerminalStripItem::TerminalStripItem(QGraphicsItem *parent) : + QetGraphicsItem { parent } +{ + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); + setAcceptHoverEvents(true); +} + +void TerminalStripItem::setTerminalStrip(TerminalStrip *strip) +{ + m_strip = strip; + m_drawer.setStrip(strip); + m_pending_strip_uuid = QUuid(); +} + +/** + * @brief TerminalStripItem::terminalStrip + * @return The strip drawed by this item + */ +QPointer TerminalStripItem::terminalStrip() const { + return m_strip; } void TerminalStripItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) @@ -62,5 +86,22 @@ void TerminalStripItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { Q_UNUSED (event); - TerminalStripEditorWindow::edit(m_strip); + if (m_strip) { + TerminalStripEditorWindow::edit(m_strip); + } +} + +void TerminalStripItem::refreshPending() +{ + if (!m_pending_strip_uuid.isNull() + && diagram() + && diagram()->project()) + { + for (const auto &strip_ : diagram()->project()->terminalStrip()) { + if (strip_->uuid() == m_pending_strip_uuid) { + setTerminalStrip(strip_); + break; + } + } + } } diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h index 4a8371592..dbdc13aea 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h +++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h @@ -19,6 +19,7 @@ #define TERMINALSTRIPITEM_H #include +#include #include "terminalstripdrawer.h" #include "../../qetgraphicsitem/qetgraphicsitem.h" @@ -27,10 +28,16 @@ class TerminalStrip; class TerminalStripItem : public QetGraphicsItem { + friend class TerminalStripItemXml; + Q_OBJECT public: TerminalStripItem(QPointer strip, QGraphicsItem *parent = nullptr); + TerminalStripItem(QGraphicsItem *parent = nullptr); + + void setTerminalStrip(TerminalStrip *strip); + QPointer terminalStrip() const; enum {Type = UserType + 1011}; int type() const override {return Type;} @@ -41,9 +48,12 @@ class TerminalStripItem : public QetGraphicsItem void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override; + void refreshPending(); + private: QPointer m_strip; TerminalStripDrawer m_drawer; + QUuid m_pending_strip_uuid; }; diff --git a/sources/diagram.cpp b/sources/diagram.cpp index 94200bfe5..2d0b3913a 100644 --- a/sources/diagram.cpp +++ b/sources/diagram.cpp @@ -18,6 +18,8 @@ #include "diagram.h" #include "ElementsCollection/elementcollectionhandler.h" +#include "TerminalStrip/GraphicsItem/terminalstripitem.h" +#include "xml/terminalstripitemxml.h" #include "QPropertyUndoCommand/qpropertyundocommand.h" #include "diagramcommands.h" #include "diagramcontent.h" @@ -873,6 +875,7 @@ QDomDocument Diagram::toXml(bool whole_content) { QVector list_images; QVector list_shapes; QVector table_vector; + QVector strip_vector; //Ckeck graphics item to "XMLise" for(QGraphicsItem *qgi : items()) @@ -922,6 +925,12 @@ QDomDocument Diagram::toXml(bool whole_content) { if (whole_content || table->isSelected()) table_vector << table; } + case TerminalStripItem::Type: { + const auto strip = static_cast(qgi); + if (whole_content || strip->isSelected()) { + strip_vector << strip; + } + } } } @@ -979,6 +988,11 @@ QDomDocument Diagram::toXml(bool whole_content) { dom_root.appendChild(tables); } + if (!strip_vector.isEmpty()) { + dom_root.appendChild(TerminalStripItemXml::toXml(strip_vector, document)); + } + + return(document); } @@ -1423,6 +1437,9 @@ bool Diagram::fromXml(QDomElement &document, added_tables << table; } + //Load terminal strip item + QVector added_strips { TerminalStripItemXml::fromXml(this, root) }; + //Translate items if a new position was given in parameter if (position != QPointF()) { @@ -1433,6 +1450,7 @@ bool Diagram::fromXml(QDomElement &document, for (auto text : qAsConst(added_texts )) added_items << text; for (auto image : qAsConst(added_images )) added_items << image; for (auto table : qAsConst(added_tables )) added_items << table; + for (const auto &strip : qAsConst(added_strips)) added_items << strip; //Get the top left corner of the rectangle that contain all added items QRectF items_rect; @@ -1473,8 +1491,9 @@ bool Diagram::fromXml(QDomElement &document, content_ptr -> m_shapes = QSet( added_shapes.begin(), added_shapes.end()); + content_ptr->m_terminal_strip.swap(added_strips); #endif - content_ptr -> m_tables = added_tables; + content_ptr->m_tables.swap(added_tables); } adjustSceneRect(); @@ -1528,20 +1547,25 @@ void Diagram::folioSequentialsFromXml(const QDomElement &root, */ void Diagram::refreshContents() { - ElementProvider provider_(this); + DiagramContent dc_(this, false); - for (Element *elmt : elements()) - { + for (auto &elmt : dc_.m_elements) { elmt->initLink(project()); - for (DynamicElementTextItem *deti : elmt->dynamicTextItems()) + for (auto &deti : elmt->dynamicTextItems()) deti->refreshLabelConnection(); } - for (Conductor *conductor : conductors()) + for (auto &conductor : dc_.conductors()) { conductor->refreshText(); + } - for (auto table : provider_.table()) + for (auto &table : qAsConst(dc_.m_tables)) { table->initLink(); + } + + for (auto &strip :qAsConst(dc_.m_terminal_strip)) { + strip->refreshPending(); + } } /** diff --git a/sources/qetproject.cpp b/sources/qetproject.cpp index 2d8caa2e8..bb078a75d 100644 --- a/sources/qetproject.cpp +++ b/sources/qetproject.cpp @@ -225,7 +225,33 @@ QETProject::ProjectState QETProject::openFile(QFile *file) if(opened_here) { file->close(); } - return ProjectState::Ok; + return ProjectState::Ok; +} + +/** + * @brief QETProject::refresh + * Refresh everything in the project. + * This is notably use when open a project from file. + */ +void QETProject::refresh() +{ + DialogWaiting *dlgWaiting { nullptr }; + if(DialogWaiting::hasInstance()) + { + dlgWaiting = DialogWaiting::instance(); + dlgWaiting->setModal(true); + dlgWaiting->show(); + } + + for(const auto &diagram : diagrams()) + { + if(dlgWaiting) + { + dlgWaiting->setProgressBar(dlgWaiting->progressBarValue()+1); + dlgWaiting->setDetail(diagram->title()); + } + diagram->refreshContents(); + } } /** @@ -1388,6 +1414,9 @@ void QETProject::readProjectXml(QDomDocument &xml_project) //Load the terminal strip readTerminalStripXml(xml_project); + //Now that all are loaded we refresh content of the project. + refresh(); + m_data_base.blockSignals(false); m_data_base.updateDB(); @@ -1461,18 +1490,6 @@ void QETProject::readDiagramsXml(QDomDocument &xml_project) "Mise en place des références croisées" "

")); } - - m_data_base.updateDB(); //All diagrams and items are created we need to update the database - - for(const auto &diagram : diagrams()) - { - if(dlgWaiting) - { - dlgWaiting->setProgressBar(dlgWaiting->progressBarValue()+1); - dlgWaiting->setDetail(diagram->title()); - } - diagram->refreshContents(); - } } /** diff --git a/sources/qetproject.h b/sources/qetproject.h index 09dfa2825..bb913ced4 100644 --- a/sources/qetproject.h +++ b/sources/qetproject.h @@ -234,6 +234,7 @@ class QETProject : public QObject void writeBackup(); void init(); ProjectState openFile(QFile *file); + void refresh(); // attributes private: diff --git a/sources/qetxml.cpp b/sources/qetxml.cpp index ec667fe3a..71d7bfea6 100644 --- a/sources/qetxml.cpp +++ b/sources/qetxml.cpp @@ -21,6 +21,7 @@ #include #include +#include #include /** @@ -917,7 +918,39 @@ bool validXmlProperty(const QDomElement& e) { if (!e.hasAttribute("value")) return false; - return true; + return true; +} + +/** + * @brief qGraphicsItemPosToXml + * Save the pos of a QGraphicsItem into an xml element. + * The tag name of the xml element is pos and there is 3 attributes: + * x, y, z. + * @param item + * @param document + * @return + */ +QDomElement qGraphicsItemPosToXml(QGraphicsItem *item, QDomDocument &document) +{ + auto dom_pos = document.createElement(QStringLiteral("pos")); + dom_pos.setAttribute(QStringLiteral("x"), QString::number(item->pos().x())); + dom_pos.setAttribute(QStringLiteral("y"), QString::number(item->pos().y())); + dom_pos.setAttribute(QStringLiteral("z"), QString::number(item->zValue())); + + return dom_pos; +} + +bool qGraphicsItemPosFromXml(QGraphicsItem *item, const QDomElement &xml_elmt) +{ + if (xml_elmt.tagName() == QLatin1String("pos")) + { + item->setX(xml_elmt.attribute(QStringLiteral("x"), QStringLiteral("0")).toDouble()); + item->setY(xml_elmt.attribute(QStringLiteral("y"), QStringLiteral("0")).toDouble()); + item->setZValue(xml_elmt.attribute(QStringLiteral("z"), QStringLiteral("0")).toInt()); + + return true; + } + return false; } } diff --git a/sources/qetxml.h b/sources/qetxml.h index 8c60b1a27..7729a80e5 100644 --- a/sources/qetxml.h +++ b/sources/qetxml.h @@ -25,6 +25,7 @@ class QDomDocument; class QDir; class QFile; class QAbstractItemModel; +class QGraphicsItem; /** *This namespace contain some function to use xml with QET. @@ -89,6 +90,10 @@ namespace QETXML QVector findInDomElement(const QDomElement &dom_elmt, const QString &tag_name); + + QDomElement qGraphicsItemPosToXml(QGraphicsItem *item, QDomDocument &document); + bool qGraphicsItemPosFromXml(QGraphicsItem *item, const QDomElement &xml_elmt); + QString boolToString(bool value); bool boolFromString(const QString &value, bool default_value = true, diff --git a/sources/xml/terminalstripitemxml.cpp b/sources/xml/terminalstripitemxml.cpp new file mode 100644 index 000000000..e624fba32 --- /dev/null +++ b/sources/xml/terminalstripitemxml.cpp @@ -0,0 +1,131 @@ +/* + Copyright 2006-2022 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "terminalstripitemxml.h" + +#include "../diagram.h" +#include "../qetproject.h" +#include "../qetxml.h" +#include "../TerminalStrip/GraphicsItem/terminalstripitem.h" +#include "../TerminalStrip/terminalstrip.h" + +#include + +const QString STRIP_ITEM_TAG_NAME { QStringLiteral("terminal_strip_item") }; +const QString STRIP_ITEMS_TAG_NAME { QStringLiteral("terminal_strip_items") }; + +/** + * @brief TerminalStripItemXml::toXml + * Save the vector of @a items as child of an xml element with tag "terminal_strip_tems" + * @param items : items to save in xml + * @param document : parent document used to create the QDomElement returned by this function. + * @return QDomElement where are saved @a items. + */ +QDomElement TerminalStripItemXml::toXml(const QVector &items, QDomDocument &document) +{ + auto dom_element = document.createElement(STRIP_ITEMS_TAG_NAME); + for (const auto &item : items) { + dom_element.appendChild(toXml(item, document)); + } + + return dom_element; +} + +/** + * @brief TerminalStripItemXml::fromXml + * Load items stored in @a xml_elmt into @a diagram + * @a xml_elmt must have a child element with tag name "terminal_strip_tems" + * @param diagram + * @param xml_elmt + * @return a vector of added terminal strip item + */ +QVector TerminalStripItemXml::fromXml(Diagram *diagram, const QDomElement &xml_elmt) +{ + QVector returned_vector; + + for (const auto &dom_elmt : QETXML::subChild(xml_elmt, + STRIP_ITEMS_TAG_NAME, + STRIP_ITEM_TAG_NAME)) + { + auto strip_item = new TerminalStripItem(); + diagram->addItem(strip_item); + returned_vector << strip_item; + + TerminalStripItemXml::fromXml(strip_item, diagram->project(), dom_elmt); + } + + return returned_vector; +} + +/** + * @brief TerminalStripItemXml::toXml + * Save @a item to an xml element with tag "terminal_strip_item" + * @param item : item to save in xml + * @param document : parent document used to create the QDomElement returned by this function. + * @return QDomElement where are saved @a item. + */ +QDomElement TerminalStripItemXml::toXml(TerminalStripItem *item, QDomDocument &document) +{ + //Terminal strip item dom element + auto dom_element = document.createElement(STRIP_ITEM_TAG_NAME); + + auto dom_strip = document.createElement(QStringLiteral("terminal_strip")); + dom_strip.setAttribute(QStringLiteral("uuid"), item->terminalStrip()->uuid().toString()); + dom_element.appendChild(dom_strip); + + dom_element.appendChild(QETXML::qGraphicsItemPosToXml(item, document)); + + return dom_element; +} + +/** + * @brief TerminalStripItemXml::fromXml + * Restor the state of a terminal strip item from @a xml_elmt. + * The @a xml_elmt tag name must be "terminal_strip_item" + * @param item + * @param project + * @param xml_elmt + * @return + */ +bool TerminalStripItemXml::fromXml(TerminalStripItem *item, QETProject *project, const QDomElement &xml_elmt) +{ + if (xml_elmt.tagName() == STRIP_ITEM_TAG_NAME) + { + bool a{false}; + + const auto ts = xml_elmt.firstChildElement(QStringLiteral("terminal_strip")); + if (!ts.isNull()) + { + const QUuid uuid_(ts.attribute(QStringLiteral("uuid"))); + item->m_pending_strip_uuid = uuid_; + + for (const auto &ts : project->terminalStrip()) { + if (ts->uuid() == uuid_) { + item->setTerminalStrip(ts); + a = true; + break; + } + } + } + + bool b{QETXML::qGraphicsItemPosFromXml(item, + xml_elmt.firstChildElement(QStringLiteral("pos")))}; + + return (a && b); + } + return false; +} diff --git a/sources/xml/terminalstripitemxml.h b/sources/xml/terminalstripitemxml.h new file mode 100644 index 000000000..c0e738f13 --- /dev/null +++ b/sources/xml/terminalstripitemxml.h @@ -0,0 +1,37 @@ +/* + Copyright 2006-2022 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#ifndef TERMINALSTRIPITEMXML_H +#define TERMINALSTRIPITEMXML_H + +#include + +class TerminalStripItem; +class QETProject; +class Diagram; + +class TerminalStripItemXml +{ + public: + static QDomElement toXml(const QVector &items, QDomDocument &document); + static QVector fromXml(Diagram *diagram, const QDomElement &xml_elmt); + + static QDomElement toXml(TerminalStripItem *item, QDomDocument &document); + static bool fromXml(TerminalStripItem *item, QETProject *project, const QDomElement &xml_elmt); +}; + +#endif // TERMINALSTRIPITEMXML_H