From d9a0b03e23a165a1cf447e3cc8a312e57b0ed95a Mon Sep 17 00:00:00 2001 From: joshua Date: Fri, 15 Jul 2022 20:48:06 +0200 Subject: [PATCH 01/12] Minor : add QGIUtility namespace --- sources/qetgraphicsitem/crossrefitem.cpp | 4 ++-- sources/qetgraphicsitem/elementtextitemgroup.cpp | 2 +- sources/qetgraphicsitem/qgraphicsitemutility.cpp | 16 +++++++++++----- sources/qetgraphicsitem/qgraphicsitemutility.h | 9 +++++++-- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/sources/qetgraphicsitem/crossrefitem.cpp b/sources/qetgraphicsitem/crossrefitem.cpp index 49700af99..3ebe3400a 100644 --- a/sources/qetgraphicsitem/crossrefitem.cpp +++ b/sources/qetgraphicsitem/crossrefitem.cpp @@ -253,13 +253,13 @@ void CrossRefItem::autoPos() { //We calcul the position according to the snapTo of the xrefproperties if (m_properties.snapTo() == XRefProperties::Bottom) - centerToBottomDiagram(this, + QGIUtility::centerToBottomDiagram(this, m_element, m_properties.offset() <= 40 ? 5 : m_properties.offset()); else - centerToParentBottom(this); + QGIUtility::centerToParentBottom(this); } /** diff --git a/sources/qetgraphicsitem/elementtextitemgroup.cpp b/sources/qetgraphicsitem/elementtextitemgroup.cpp index c36b5be74..d4a20bdd0 100644 --- a/sources/qetgraphicsitem/elementtextitemgroup.cpp +++ b/sources/qetgraphicsitem/elementtextitemgroup.cpp @@ -861,7 +861,7 @@ void ElementTextItemGroup::autoPos() } } qreal r = rotation(); - centerToBottomDiagram(this, m_parent_element, offset); + QGIUtility::centerToBottomDiagram(this, m_parent_element, offset); //centerToBottomDiagram change the rotation of this group if needed, //but setRotation is not a virtual function of QGraphicsItem, and the function centerToBottomDiagram //work with a QGraphicsItem. So we emit the signal if rotation changed diff --git a/sources/qetgraphicsitem/qgraphicsitemutility.cpp b/sources/qetgraphicsitem/qgraphicsitemutility.cpp index d314997c2..765980f77 100644 --- a/sources/qetgraphicsitem/qgraphicsitemutility.cpp +++ b/sources/qetgraphicsitem/qgraphicsitemutility.cpp @@ -23,6 +23,9 @@ #include #include +namespace QGIUtility +{ + /** @brief centerToParentBottom Center the item at the bottom of is parent. @@ -51,10 +54,10 @@ bool centerToParentBottom(QGraphicsItem *item) { @param offset @return true if element is centered else false (element_to_follow have not diagram) */ -#include "elementtextitemgroup.h" -#include "crossrefitem.h" -bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, qreal offset) { - if (! element_to_follow -> diagram()) { +bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, qreal offset) +{ + if (! element_to_follow -> diagram()) + { qDebug() << "qgraphicsitemutility centerAtBottomDiagram : Element_to_follow have not diagram"; return false; } @@ -81,8 +84,11 @@ bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_f rot += parent->rotation(); parent = parent->parentItem(); } - if(rot != 0) + if(rot != 0) { item_to_center->setRotation(item_to_center->rotation() - rot); + } return true; } +} + diff --git a/sources/qetgraphicsitem/qgraphicsitemutility.h b/sources/qetgraphicsitem/qgraphicsitemutility.h index 453849d46..2bb660696 100644 --- a/sources/qetgraphicsitem/qgraphicsitemutility.h +++ b/sources/qetgraphicsitem/qgraphicsitemutility.h @@ -17,11 +17,16 @@ */ #ifndef QGRAPHICSITEMUTILITY_H #define QGRAPHICSITEMUTILITY_H + #include + class QGraphicsItem; class Element; -bool centerToParentBottom (QGraphicsItem *item); -bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, qreal offset = 0 ); +namespace QGIUtility +{ + bool centerToParentBottom (QGraphicsItem *item); + bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, qreal offset = 0 ); +} #endif // QGRAPHICSITEMUTILITY_H From ff80453f2c80c34e64e9959bcf6a4170e64da487 Mon Sep 17 00:00:00 2001 From: joshua Date: Sat, 27 Aug 2022 21:24:25 +0200 Subject: [PATCH 02/12] Terminal strip item can be added to diagram Initial commit about graphics item of a terminal strip, Work in progress. --- qelectrotech.pro | 6 +- .../GraphicsItem/terminalstripitem.cpp | 49 ++++ .../GraphicsItem/terminalstripitem.h | 44 ++++ .../terminalstriplayoutpattern.cpp | 247 ++++++++++++++++++ .../GraphicsItem/terminalstriplayoutpattern.h | 130 +++++++++ .../ui/addterminalstripitemdialog.cpp | 85 ++++++ .../ui/addterminalstripitemdialog.h | 51 ++++ .../ui/addterminalstripitemdialog.ui | 87 ++++++ sources/qetdiagrameditor.cpp | 14 + sources/qetgraphicsitem/qetgraphicsitem.cpp | 16 ++ sources/qetgraphicsitem/qetgraphicsitem.h | 9 +- .../qetgraphicsitem/qgraphicsitemutility.cpp | 14 + .../qetgraphicsitem/qgraphicsitemutility.h | 2 + 13 files changed, 751 insertions(+), 3 deletions(-) create mode 100644 sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp create mode 100644 sources/TerminalStrip/GraphicsItem/terminalstripitem.h create mode 100644 sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp create mode 100644 sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.h create mode 100644 sources/TerminalStrip/ui/addterminalstripitemdialog.cpp create mode 100644 sources/TerminalStrip/ui/addterminalstripitemdialog.h create mode 100644 sources/TerminalStrip/ui/addterminalstripitemdialog.ui diff --git a/qelectrotech.pro b/qelectrotech.pro index 997e6511f..e8d97d08d 100644 --- a/qelectrotech.pro +++ b/qelectrotech.pro @@ -163,7 +163,8 @@ HEADERS += $$files(sources/*.h) $$files(sources/ui/*.h) \ $$files(sources/print/*.h) \ $$files(sources/TerminalStrip/*.h) \ $$files(sources/TerminalStrip/ui/*.h) \ - $$files(sources/TerminalStrip/UndoCommand/*.h) + $$files(sources/TerminalStrip/UndoCommand/*.h) \ + $$files(sources/TerminalStrip/GraphicsItem/*.h) SOURCES += $$files(sources/*.cpp) \ $$files(sources/editor/*.cpp) \ @@ -199,7 +200,8 @@ SOURCES += $$files(sources/*.cpp) \ $$files(sources/print/*.cpp) \ $$files(sources/TerminalStrip/*.cpp) \ $$files(sources/TerminalStrip/ui/*.cpp) \ - $$files(sources/TerminalStrip/UndoCommand/*.cpp) + $$files(sources/TerminalStrip/UndoCommand/*.cpp) \ + $$files(sources/TerminalStrip/GraphicsItem/*.cpp) # Needed for use promote QTreeWidget in terminalstripeditor.ui INCLUDEPATH += sources/TerminalStrip/ui diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp b/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp new file mode 100644 index 000000000..48b3de916 --- /dev/null +++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp @@ -0,0 +1,49 @@ +/* + 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 "terminalstripitem.h" +#include "../../qetgraphicsitem/qgraphicsitemutility.h" + +TerminalStripItem::TerminalStripItem(QPointer strip, QGraphicsItem *parent) : + QetGraphicsItem{parent}, + m_strip{strip}, + m_drawer{strip} +{ + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); + setAcceptHoverEvents(true); +} + +void TerminalStripItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + m_drawer.paint(painter); + + if (isSelected() || isHovered()) + { + QGIUtility::drawBoundingRectSelection(this, painter); + } +} + +QRectF TerminalStripItem::boundingRect() const +{ + auto br_ = m_drawer.boundingRect(); + br_.adjust(-5,-5,5,5); + + return br_; +} diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h new file mode 100644 index 000000000..e3410037e --- /dev/null +++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h @@ -0,0 +1,44 @@ +/* + 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 TERMINALSTRIPITEM_H +#define TERMINALSTRIPITEM_H + +#include + +#include "terminalstriplayoutpattern.h" +#include "../../qetgraphicsitem/qetgraphicsitem.h" + +class TerminalStrip; + +class TerminalStripItem : public QetGraphicsItem +{ + Q_OBJECT + + public: + TerminalStripItem(QPointer strip, QGraphicsItem *parent = nullptr); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + QRectF boundingRect() const override; + + private: + QPointer m_strip; + TerminalStripDrawer m_drawer; + +}; + +#endif // TERMINALSTRIPITEM_H diff --git a/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp b/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp new file mode 100644 index 000000000..a299c9a2a --- /dev/null +++ b/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp @@ -0,0 +1,247 @@ +/* + 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 "terminalstriplayoutpattern.h" + +#include "../physicalterminal.h" +#include "../realterminal.h" +#include "../terminalstrip.h" + +#include + +/** + * @brief TerminalStripDrawer::TerminalStripDrawer + * @param strip + * @param pattern + */ +TerminalStripDrawer::TerminalStripDrawer(QPointer strip) : + m_strip(strip) +{} + +/** + * @brief TerminalStripDrawer::paint + * @param painter + */ +void TerminalStripDrawer::paint(QPainter *painter) +{ + if (m_strip) + { + //To draw text, QPainter need a Qrect. Instead of create an instance + //for each text, we re-use the same instance of QRect. + QRect text_rect; + painter->save(); + + auto pen_{painter->pen()}; + pen_.setColor(Qt::black); + pen_.setWidth(1); + + auto brush_ = painter->brush(); + brush_.setColor(Qt::white); + + painter->setPen(pen_); + painter->setBrush(brush_); + + //Draw header + painter->drawRect(m_pattern.m_header_rect); + + //Draw the header text + painter->save(); + + if (m_pattern.m_header_text_orientation == Qt::Horizontal) + { + text_rect.setRect(0,m_pattern.m_header_rect.y(),m_pattern.m_header_rect.width(),m_pattern.m_header_rect.height()); + } + else + { + painter->translate(m_pattern.m_header_rect.bottomLeft()); + painter->rotate(270); + text_rect.setRect(0,0,m_pattern.m_header_rect.height(),m_pattern.m_header_rect.width()); + } + + const auto text_{m_strip->installation() + " " + m_strip->location() + " " + m_strip->name()}; + painter->drawText(text_rect, text_, m_pattern.headerTextOption()); + painter->restore(); + + //Move painter pos to next drawing + painter->translate(m_pattern.m_header_rect.width(),0); + + //Draw spacer + painter->drawRect(m_pattern.m_spacer_rect); + //Move painter pos to next drawing + painter->translate(m_pattern.m_spacer_rect.width(),0); + + + //Draw terminals + const auto terminals_text_rect{m_pattern.m_terminals_text_rect}; + const auto terminals_text_orientation{m_pattern.m_terminals_text_orientation}; + const auto terminals_text_option{m_pattern.terminalsTextOption()}; + QRect terminal_rect; + + //Loop over physical terminals + for (const auto &physical_t : m_strip->physicalTerminal()) + { + //Get the good offset according to how many level have the current physical terminal + const QVector> real_terminal{physical_t->realTerminals()}; + const auto real_t_count{real_terminal.size()}; + const auto offset_{4 - real_t_count}; + + //Loop over real terminals + for (auto i=0 ; i= 4) { + break; + } + + terminal_rect = m_pattern.m_terminal_rect[index_]; + painter->drawRect(terminal_rect); + + //Draw text + painter->save(); + if (terminals_text_orientation[index_] == Qt::Horizontal) + { + text_rect = terminals_text_rect[index_]; + } + else + { + const auto rect_{terminals_text_rect[index_]}; + painter->translate(rect_.bottomLeft()); + painter->rotate(270); + text_rect.setRect(0, 0, rect_.height(), rect_.width()); + } + + const auto shared_real_terminal{real_terminal[i]}; + painter->drawText(text_rect, + shared_real_terminal ? shared_real_terminal->label() : QLatin1String(), + terminals_text_option[index_]); + painter->restore(); + + //Move painter pos to next drawing + painter->translate(terminal_rect.width(),0); + } + } + + painter->restore(); + } +} + +QRectF TerminalStripDrawer::boundingRect() const +{ + return QRect{0, 0, width(), height()};; +} + +int TerminalStripDrawer::height() const +{ + auto height_{m_pattern.m_header_rect.y() + m_pattern.m_header_rect.height()}; + + height_ = std::max(height_, m_pattern.m_spacer_rect.y() + m_pattern.m_spacer_rect.height()); + + for (const auto &rect : m_pattern.m_terminal_rect) { + height_ = std::max(height_, rect.y() + rect.height()); + } + + return height_; +} + +int TerminalStripDrawer::width() const +{ + int width_{m_pattern.m_header_rect.width() + m_pattern.m_spacer_rect.width()}; + + if (m_strip) + { + //Loop over physical terminals + for (const auto &physical_t : m_strip->physicalTerminal()) + { + //Get the good offset according to how many level have the current physical terminal + const QVector> real_terminal{physical_t->realTerminals()}; + const auto real_t_count{real_terminal.size()}; + const auto offset_{4 - real_t_count}; + + //Loop over real terminals + for (auto i=0 ; i= 4) { + break; + } + + width_ += m_pattern.m_terminal_rect[index_].width(); + } + } + } + + return width_; +} + +TerminalStripLayoutPattern::TerminalStripLayoutPattern() +{ + updateHeaderTextOption(); + updateTerminalsTextOption(); +} + +void TerminalStripLayoutPattern::setHeaderTextAlignment(const Qt::Alignment &alignment) +{ + m_header_text_alignment = alignment; + updateHeaderTextOption(); +} + +Qt::Alignment TerminalStripLayoutPattern::headerTextAlignment() const +{ + return m_header_text_alignment; +} + +QTextOption TerminalStripLayoutPattern::headerTextOption() const { + return m_header_text_option; +} + +void TerminalStripLayoutPattern::setTerminalsTextAlignment(const QVector &alignment) +{ + m_terminals_text_alignment = alignment; + updateTerminalsTextOption(); +} + +QVector TerminalStripLayoutPattern::terminalsTextAlignment() const +{ + return m_terminals_text_alignment; +} + +QVector TerminalStripLayoutPattern::terminalsTextOption() const +{ + return m_terminals_text_option; +} + +void TerminalStripLayoutPattern::updateHeaderTextOption() +{ + m_header_text_option.setAlignment(m_header_text_alignment); + m_header_text_option.setWrapMode(QTextOption::WordWrap); +} + +void TerminalStripLayoutPattern::updateTerminalsTextOption() +{ + if (m_terminals_text_option.size() == + m_terminals_text_alignment.size()) + { + for (auto i = 0 ; i. +*/ +#ifndef TERMINALSTRIPLAYOUTPATTERN_H +#define TERMINALSTRIPLAYOUTPATTERN_H + +#include +#include +#include +#include +#include + +class QPainter; +class TerminalStrip; + +/** + * @brief The TerminalStripLayoutPattern class + * A class with all values used to define how a terminal strip must be drawn. + * Most of the value are public, some values are private and have getter / setter + * because when these values change we need to compute the change. + * + * The values with name '_y_offset' mean offset is relating to the top + * of the QGraphicsItem used to display the terminal strip. + * + * The terminal strip can display up to 4 terminal level, + * the value used for multilevel terminal are stored in several QVector (m_terminal_y_offset, m_terminal_height, m_bridge_point_y_offset). + * The order of the values are from the most back terminal to the front terminal. + */ +class TerminalStripLayoutPattern +{ + public: + TerminalStripLayoutPattern(); + + //Header of terminal strip + QRect m_header_rect{0,30,50,130}; + Qt::Orientation m_header_text_orientation{Qt::Horizontal}; + void setHeaderTextAlignment(const Qt::Alignment &alignment); + Qt::Alignment headerTextAlignment() const; + QTextOption headerTextOption() const; + + //Spacer between the header and the terminals + QRect m_spacer_rect{0, 50, 10, 90}; + + //Terminals + QVector m_terminal_rect + { + QRect{0, 0, 20, 190}, + QRect{0, 10, 20, 170}, + QRect{0, 20, 20, 150}, + QRect{0, 30, 20, 130} + }; + + void setTerminalsTextAlignment(const QVector &alignment); + QVector terminalsTextAlignment() const; + QVector terminalsTextOption() const; + + QVector m_terminals_text_rect + { + QRect{0,35,20,50}, + QRect{0,35,20,50}, + QRect{0,35,20,50}, + QRect{0,35,20,50} + }; + QVector m_terminals_text_orientation + { + Qt::Vertical, + Qt::Vertical, + Qt::Vertical, + Qt::Vertical + }; + + int m_bridge_point_d{5}; + QVector m_bridge_point_y_offset{50,70,90,110}; + + private: + void updateHeaderTextOption(); + void updateTerminalsTextOption(); + + private: + Qt::Alignment m_header_text_alignment{Qt::AlignCenter}; + QTextOption m_header_text_option; + + QVector m_terminals_text_alignment + { + Qt::AlignRight | Qt::AlignVCenter, + Qt::AlignRight | Qt::AlignVCenter, + Qt::AlignRight | Qt::AlignVCenter, + Qt::AlignRight | Qt::AlignVCenter + }; + QVector m_terminals_text_option + { + QTextOption(), + QTextOption(), + QTextOption(), + QTextOption() + }; +}; + +class TerminalStripDrawer +{ + public: + TerminalStripDrawer(QPointer strip); + void paint(QPainter *painter); + + QRectF boundingRect() const; + + private: + int height() const; + int width() const; + + private: + QPointer m_strip; + TerminalStripLayoutPattern m_pattern; +}; + +#endif // TERMINALSTRIPLAYOUTPATTERN_H diff --git a/sources/TerminalStrip/ui/addterminalstripitemdialog.cpp b/sources/TerminalStrip/ui/addterminalstripitemdialog.cpp new file mode 100644 index 000000000..44f54de47 --- /dev/null +++ b/sources/TerminalStrip/ui/addterminalstripitemdialog.cpp @@ -0,0 +1,85 @@ +/* + 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 "addterminalstripitemdialog.h" +#include "ui_addterminalstripitemdialog.h" + +#include "../terminalstrip.h" +#include "../GraphicsItem/terminalstripitem.h" +#include "../../diagram.h" + +void AddTerminalStripItemDialog::openDialog(Diagram *diagram, QWidget *parent) +{ + AddTerminalStripItemDialog d(diagram->project(), parent); + if (d.exec()) + { + const auto strip_{d.selectedTerminalStrip()}; + if (strip_) + { + auto item_ = new TerminalStripItem(strip_); + diagram->addItem(item_); + item_->setPos(20, 20); + } + } +} + +AddTerminalStripItemDialog::AddTerminalStripItemDialog(QETProject *project, QWidget *parent) : + QDialog{parent}, + m_project{project}, + ui{new Ui::AddTerminalStripItemDialog} +{ + ui->setupUi(this); + fillComboBox(); +} + +AddTerminalStripItemDialog::~AddTerminalStripItemDialog() +{ + delete ui; +} + +/** + * @brief AddTerminalStripItemDialog::selectedTerminalStrip + * @return The selected terminal strip or nullptr if no one is selected + * or error encounted. + */ +TerminalStrip *AddTerminalStripItemDialog::selectedTerminalStrip() const +{ + if (m_project) + { + QUuid uuid_{ui->m_terminal_strip_cb->currentData().toUuid()}; + for (const auto &strip_ : m_project->terminalStrip()) + { + if (strip_->uuid() == uuid_) { + return strip_; + } + } + } + + return nullptr; +} + +void AddTerminalStripItemDialog::fillComboBox() +{ + if (m_project) + { + for (const auto strip_ : m_project->terminalStrip()) + { + const auto text{strip_->installation() + " " + strip_->location() + " " + strip_->name()}; + ui->m_terminal_strip_cb->addItem(text, strip_->uuid()); + } + } +} diff --git a/sources/TerminalStrip/ui/addterminalstripitemdialog.h b/sources/TerminalStrip/ui/addterminalstripitemdialog.h new file mode 100644 index 000000000..e7eae36f9 --- /dev/null +++ b/sources/TerminalStrip/ui/addterminalstripitemdialog.h @@ -0,0 +1,51 @@ +/* + 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 ADDTERMINALSTRIPITEMDIALOG_H +#define ADDTERMINALSTRIPITEMDIALOG_H + +#include +#include + +class Diagram; +class QETDiagramEditor; +class QETProject; +class TerminalStrip; + +namespace Ui { + class AddTerminalStripItemDialog; +} + +class AddTerminalStripItemDialog : public QDialog +{ + Q_OBJECT + + public: + static void openDialog(Diagram *diagram, QWidget *parent = nullptr); + + private: + explicit AddTerminalStripItemDialog(QETProject *project, QWidget *parent = nullptr); + ~AddTerminalStripItemDialog(); + TerminalStrip *selectedTerminalStrip() const; + void fillComboBox(); + + private: + QPointer m_project; + Ui::AddTerminalStripItemDialog *ui; +}; + +#endif // ADDTERMINALSTRIPITEMDIALOG_H diff --git a/sources/TerminalStrip/ui/addterminalstripitemdialog.ui b/sources/TerminalStrip/ui/addterminalstripitemdialog.ui new file mode 100644 index 000000000..34c4f937d --- /dev/null +++ b/sources/TerminalStrip/ui/addterminalstripitemdialog.ui @@ -0,0 +1,87 @@ + + + AddTerminalStripItemDialog + + + + 0 + 0 + 326 + 100 + + + + Dialog + + + + + + Ajouter le plan de bornes suivant : + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + AddTerminalStripItemDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AddTerminalStripItemDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index 08ddcac02..db362aa0b 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -44,6 +44,7 @@ #include "diagram.h" #include "TerminalStrip/ui/terminalstripeditorwindow.h" #include "ui/diagrameditorhandlersizewidget.h" +#include "TerminalStrip/ui/addterminalstripitemdialog.h" #ifdef BUILD_WITHOUT_KF5 #else @@ -664,6 +665,7 @@ void QETDiagramEditor::setUpActions() QAction *add_rectangle = m_add_item_actions_group.addAction(QET::Icons::PartRectangle, tr("Ajouter un rectangle")); QAction *add_ellipse = m_add_item_actions_group.addAction(QET::Icons::PartEllipse, tr("Ajouter une ellipse")); QAction *add_polyline = m_add_item_actions_group.addAction(QET::Icons::PartPolygon, tr("Ajouter une polyligne")); + QAction *add_terminal_strip = m_add_item_actions_group.addAction(QET::Icons::TerminalStrip, tr("Ajouter un plan de bornes")); add_text ->setStatusTip(tr("Ajoute un champ de texte sur le folio actuel")); add_image ->setStatusTip(tr("Ajoute une image sur le folio actuel")); @@ -671,6 +673,7 @@ void QETDiagramEditor::setUpActions() add_rectangle->setStatusTip(tr("Ajoute un rectangle sur le folio actuel")); add_ellipse ->setStatusTip(tr("Ajoute une ellipse sur le folio actuel")); add_polyline ->setStatusTip(tr("Ajoute une polyligne sur le folio actuel")); + add_terminal_strip->setStatusTip(tr("Ajoute un plan de bornier sur le folio actuel")); add_text ->setData("text"); add_image ->setData("image"); @@ -678,6 +681,7 @@ void QETDiagramEditor::setUpActions() add_rectangle->setData("rectangle"); add_ellipse ->setData("ellipse"); add_polyline ->setData("polyline"); + add_terminal_strip->setData(QStringLiteral("terminal_strip")); for(QAction *action : m_add_item_actions_group.actions()) { action->setCheckable(true); @@ -1430,7 +1434,17 @@ void QETDiagramEditor::addItemGroupTriggered(QAction *action) diagram_event = deai; } else if (value == "text") + { diagram_event = new DiagramEventAddText(d); + } + else if (value == QLatin1String("terminal_strip")) + { + const auto diagram_view{currentDiagramView()}; + if (diagram_view) + { + AddTerminalStripItemDialog::openDialog(diagram_view->diagram(), this); + } + } if (diagram_event) { diff --git a/sources/qetgraphicsitem/qetgraphicsitem.cpp b/sources/qetgraphicsitem/qetgraphicsitem.cpp index e1c9bc6a0..6c952e25c 100644 --- a/sources/qetgraphicsitem/qetgraphicsitem.cpp +++ b/sources/qetgraphicsitem/qetgraphicsitem.cpp @@ -64,6 +64,10 @@ void QetGraphicsItem::setPos(qreal x, qreal y) { setPos(QPointF(x, y)); } +bool QetGraphicsItem::isHovered() const { + return m_hovered; +} + /** @brief QetGraphicsItem::state @return the current state of this item @@ -155,3 +159,15 @@ void QetGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) event->accept(); } } + +void QetGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + m_hovered = true; + QGraphicsObject::hoverEnterEvent(event); +} + +void QetGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + m_hovered = false; + QGraphicsObject::hoverLeaveEvent(event); +} diff --git a/sources/qetgraphicsitem/qetgraphicsitem.h b/sources/qetgraphicsitem/qetgraphicsitem.h index 5c7742c35..5c33b63b5 100644 --- a/sources/qetgraphicsitem/qetgraphicsitem.h +++ b/sources/qetgraphicsitem/qetgraphicsitem.h @@ -1,4 +1,4 @@ -/* +/* Copyright 2006-2021 The QElectroTech Team This file is part of QElectroTech. @@ -42,6 +42,8 @@ class QetGraphicsItem : public QGraphicsObject {return is_movable_;} virtual void setMovable (bool movable) { is_movable_ = movable;} + bool isHovered() const; + virtual void editProperty () {} virtual QString name ()const {return QString("");} @@ -54,6 +56,8 @@ class QetGraphicsItem : public QGraphicsObject void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override; void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; + void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override; protected: bool is_movable_; @@ -62,6 +66,9 @@ class QetGraphicsItem : public QGraphicsObject QPointF m_mouse_to_origin_movement; QET::GraphicsItemState m_state = QET:: GIOK; + private: + bool m_hovered{false}; + }; #endif // QETGRAPHICSITEM_H diff --git a/sources/qetgraphicsitem/qgraphicsitemutility.cpp b/sources/qetgraphicsitem/qgraphicsitemutility.cpp index 765980f77..1be9f32a2 100644 --- a/sources/qetgraphicsitem/qgraphicsitemutility.cpp +++ b/sources/qetgraphicsitem/qgraphicsitemutility.cpp @@ -90,5 +90,19 @@ bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_f return true; } + +void drawBoundingRectSelection(QGraphicsItem *item, QPainter *painter) +{ + painter->save(); + QPen t; + t.setColor(Qt::gray); + t.setStyle(Qt::DashDotLine); + t.setCosmetic(true); + + painter->setPen(t); + painter->drawRoundedRect(item->boundingRect(),10,10); + painter->restore(); +} + } diff --git a/sources/qetgraphicsitem/qgraphicsitemutility.h b/sources/qetgraphicsitem/qgraphicsitemutility.h index 2bb660696..09f9d292a 100644 --- a/sources/qetgraphicsitem/qgraphicsitemutility.h +++ b/sources/qetgraphicsitem/qgraphicsitemutility.h @@ -22,11 +22,13 @@ class QGraphicsItem; class Element; +class QPainter; namespace QGIUtility { bool centerToParentBottom (QGraphicsItem *item); bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, qreal offset = 0 ); + void drawBoundingRectSelection(QGraphicsItem *item, QPainter *painter); } #endif // QGRAPHICSITEMUTILITY_H From 21de926367d6cc315812ca9ccab43c835ee3f81d Mon Sep 17 00:00:00 2001 From: joshua Date: Sun, 23 Oct 2022 19:30:58 +0200 Subject: [PATCH 03/12] TerminalStripItem : Draw terminal bridge --- .../terminalstriplayoutpattern.cpp | 39 +++++++++++++++++++ sources/TerminalStrip/terminalstripbridge.cpp | 8 ++++ sources/TerminalStrip/terminalstripbridge.h | 1 + 3 files changed, 48 insertions(+) diff --git a/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp b/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp index a299c9a2a..c10c2e1e5 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp +++ b/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp @@ -20,6 +20,7 @@ #include "../physicalterminal.h" #include "../realterminal.h" #include "../terminalstrip.h" +#include "../terminalstripbridge.h" #include @@ -79,10 +80,13 @@ void TerminalStripDrawer::paint(QPainter *painter) //Move painter pos to next drawing painter->translate(m_pattern.m_header_rect.width(),0); + int x_offset{m_pattern.m_header_rect.width()}; + //Draw spacer painter->drawRect(m_pattern.m_spacer_rect); //Move painter pos to next drawing painter->translate(m_pattern.m_spacer_rect.width(),0); + x_offset += m_pattern.m_spacer_rect.width(); //Draw terminals @@ -91,6 +95,8 @@ void TerminalStripDrawer::paint(QPainter *painter) const auto terminals_text_option{m_pattern.terminalsTextOption()}; QRect terminal_rect; + QHash> bridges_anchor_points; + //Loop over physical terminals for (const auto &physical_t : m_strip->physicalTerminal()) { @@ -108,6 +114,7 @@ void TerminalStripDrawer::paint(QPainter *painter) } terminal_rect = m_pattern.m_terminal_rect[index_]; + //Draw terminal rect painter->drawRect(terminal_rect); //Draw text @@ -130,12 +137,44 @@ void TerminalStripDrawer::paint(QPainter *painter) terminals_text_option[index_]); painter->restore(); + //Add bridge anchor + if (shared_real_terminal->isBridged()) + { + painter->save(); + if (const auto bridge_ = shared_real_terminal->bridge()) + { + const auto anchor_center{m_pattern.m_bridge_point_d/2}; + painter->setBrush(Qt::SolidPattern); + painter->drawEllipse(QPointF{terminal_rect.width()/2, m_pattern.m_bridge_point_y_offset[index_]}, + anchor_center, + anchor_center); + + auto anchor_points{bridges_anchor_points.value(bridge_->uuid())}; + anchor_points.append(QPointF{x_offset + terminal_rect.width()/2, + m_pattern.m_bridge_point_y_offset[index_]}); + bridges_anchor_points.insert(bridge_->uuid(), anchor_points); + } + painter->restore(); + } + //Move painter pos to next drawing painter->translate(terminal_rect.width(),0); + x_offset += terminal_rect.width(); } } painter->restore(); + + //Draw the bridges + for (const auto &points_ : qAsConst(bridges_anchor_points)) + { + painter->save(); + auto pen_{painter->pen()}; + pen_.setWidth(2); + painter->setPen(pen_); + painter->drawPolyline(QPolygonF{points_}); + painter->restore(); + } } } diff --git a/sources/TerminalStrip/terminalstripbridge.cpp b/sources/TerminalStrip/terminalstripbridge.cpp index 368bf956c..d4a89f215 100644 --- a/sources/TerminalStrip/terminalstripbridge.cpp +++ b/sources/TerminalStrip/terminalstripbridge.cpp @@ -120,6 +120,14 @@ void TerminalStripBridge::fromXml(const QDomElement &dom_element) } } +/** + * @brief TerminalStripBridge::uuid + * @return The uuid of this terminal + */ +QUuid TerminalStripBridge::uuid() const noexcept { + return m_uuid; +} + /** * @brief TerminalStripBridge::addTerminals * @param real_terminals diff --git a/sources/TerminalStrip/terminalstripbridge.h b/sources/TerminalStrip/terminalstripbridge.h index ef53db5f2..e78b5a16b 100644 --- a/sources/TerminalStrip/terminalstripbridge.h +++ b/sources/TerminalStrip/terminalstripbridge.h @@ -46,6 +46,7 @@ class TerminalStripBridge static QString xmlTagName() {return QStringLiteral("terminal_strip_bridge");} QDomElement toXml(QDomDocument &parent_document) const; void fromXml(const QDomElement &dom_element); + QUuid uuid() const noexcept; private: bool addTerminals(const QVector> &real_terminals); From 7fede2277f93ec5b206eca5bc0d8637ecd5c414d Mon Sep 17 00:00:00 2001 From: joshua Date: Tue, 8 Nov 2022 19:20:32 +0100 Subject: [PATCH 04/12] Add and move terminal strip item are now managed by undo command --- dev_doc/enum_type_of_QGraphicsItem | 1 + .../GraphicsItem/terminalstripitem.cpp | 8 +++++ .../GraphicsItem/terminalstripitem.h | 4 +++ .../ui/addterminalstripitemdialog.cpp | 11 ++++--- sources/diagramcommands.cpp | 18 ++++++----- sources/diagramcontent.cpp | 32 ++++++++++++------- sources/diagramcontent.h | 7 ++-- sources/elementsmover.cpp | 2 +- sources/qet.cpp | 11 ++++++- sources/qet.h | 9 +++++- 10 files changed, 74 insertions(+), 29 deletions(-) diff --git a/dev_doc/enum_type_of_QGraphicsItem b/dev_doc/enum_type_of_QGraphicsItem index 068b37d70..33e5c3e57 100644 --- a/dev_doc/enum_type_of_QGraphicsItem +++ b/dev_doc/enum_type_of_QGraphicsItem @@ -11,6 +11,7 @@ DiagramImageItem + 1007 QetShapItem + 1008 crossRefItem + 1009 DynamiqueElementTextItem + 1010 +TerminalStripItem +1011 ElementPrimitiveDecorator + 2200 ###ELEMENT EDITOR### diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp b/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp index 48b3de916..8b4ebf94c 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp +++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp @@ -47,3 +47,11 @@ QRectF TerminalStripItem::boundingRect() const return br_; } + +/** + * @brief TerminalStripItem::name + * @return usual name of this item + */ +QString TerminalStripItem::name() const { + return tr("plan de bornes"); +} diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h index e3410037e..1fbb4f22c 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h +++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h @@ -32,8 +32,12 @@ class TerminalStripItem : public QetGraphicsItem public: TerminalStripItem(QPointer strip, QGraphicsItem *parent = nullptr); + enum {Type = UserType + 1011}; + int type() const override {return Type;} + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; QRectF boundingRect() const override; + QString name() const override; private: QPointer m_strip; diff --git a/sources/TerminalStrip/ui/addterminalstripitemdialog.cpp b/sources/TerminalStrip/ui/addterminalstripitemdialog.cpp index 44f54de47..c6c843b3d 100644 --- a/sources/TerminalStrip/ui/addterminalstripitemdialog.cpp +++ b/sources/TerminalStrip/ui/addterminalstripitemdialog.cpp @@ -18,6 +18,7 @@ #include "addterminalstripitemdialog.h" #include "ui_addterminalstripitemdialog.h" +#include "../../undocommand/addgraphicsobjectcommand.h" #include "../terminalstrip.h" #include "../GraphicsItem/terminalstripitem.h" #include "../../diagram.h" @@ -32,7 +33,9 @@ void AddTerminalStripItemDialog::openDialog(Diagram *diagram, QWidget *parent) { auto item_ = new TerminalStripItem(strip_); diagram->addItem(item_); - item_->setPos(20, 20); + item_->setPos(50, 50); + + diagram->project()->undoStack()->push(new AddGraphicsObjectCommand(item_, diagram, QPointF{50, 50})); } } } @@ -60,8 +63,8 @@ TerminalStrip *AddTerminalStripItemDialog::selectedTerminalStrip() const { if (m_project) { - QUuid uuid_{ui->m_terminal_strip_cb->currentData().toUuid()}; - for (const auto &strip_ : m_project->terminalStrip()) + const QUuid uuid_{ui->m_terminal_strip_cb->currentData().toUuid()}; + for (auto &&strip_ : m_project->terminalStrip()) { if (strip_->uuid() == uuid_) { return strip_; @@ -76,7 +79,7 @@ void AddTerminalStripItemDialog::fillComboBox() { if (m_project) { - for (const auto strip_ : m_project->terminalStrip()) + for (auto &&strip_ : m_project->terminalStrip()) { const auto text{strip_->installation() + " " + strip_->location() + " " + strip_->name()}; ui->m_terminal_strip_cb->addItem(text, strip_->uuid()); diff --git a/sources/diagramcommands.cpp b/sources/diagramcommands.cpp index 4665d312b..46e41b601 100644 --- a/sources/diagramcommands.cpp +++ b/sources/diagramcommands.cpp @@ -176,7 +176,8 @@ MoveElementsCommand::MoveElementsCommand( DiagramContent::ConductorsToMove | DiagramContent::Images | DiagramContent::Shapes | - DiagramContent::ElementTextFields + DiagramContent::ElementTextFields | + DiagramContent::TerminalStrip ); setText( @@ -236,13 +237,14 @@ void MoveElementsCommand::move(const QPointF &actual_movement) typedef DiagramContent dc; //Move every movable items, except conductor - for (QGraphicsItem *qgi : content_to_move.items(dc::Elements - | dc::TextFields - | dc::Images - | dc::Shapes - | dc::TextGroup - | dc::ElementTextFields - | dc::Tables)) + for (auto &&qgi : content_to_move.items(dc::Elements + | dc::TextFields + | dc::Images + | dc::Shapes + | dc::TextGroup + | dc::ElementTextFields + | dc::Tables + | dc::TerminalStrip)) { //If curent item have parent, and parent item is in content_to_move //we don't apply movement to this item, because this item will be moved by is parent. diff --git a/sources/diagramcontent.cpp b/sources/diagramcontent.cpp index 3842490cd..1f03a6a79 100644 --- a/sources/diagramcontent.cpp +++ b/sources/diagramcontent.cpp @@ -28,6 +28,7 @@ #include "qetgraphicsitem/independenttextitem.h" #include "qetgraphicsitem/qetshapeitem.h" #include "qetgraphicsitem/terminal.h" +#include "TerminalStrip/GraphicsItem/terminalstripitem.h" #include @@ -54,7 +55,7 @@ DiagramContent::DiagramContent(Diagram *diagram, bool selected) : item_list = diagram->items(); } - for (auto item : item_list) + for (const auto &item : qAsConst(item_list)) { switch (item->type()) { @@ -88,6 +89,7 @@ DiagramContent::DiagramContent(Diagram *diagram, bool selected) : break; } case QetGraphicsTableItem::Type: { m_tables << qgraphicsitem_cast(item); break;} + case TerminalStripItem::Type : {m_terminal_strip << qgraphicsitem_cast(item); break;} } } @@ -194,13 +196,14 @@ bool DiagramContent::hasDeletableItems() const { for(QGraphicsItem *qgi : m_selected_items) { - if (qgi->type() == Element::Type || - qgi->type() == Conductor::Type || - qgi->type() == IndependentTextItem::Type || - qgi->type() == QetShapeItem::Type || - qgi->type() == DiagramImageItem::Type || - qgi->type() == DynamicElementTextItem::Type || - qgi->type() == QetGraphicsTableItem::Type) + if (qgi->type() == Element::Type + || qgi->type() == Conductor::Type + || qgi->type() == IndependentTextItem::Type + || qgi->type() == QetShapeItem::Type + || qgi->type() == DiagramImageItem::Type + || qgi->type() == DynamicElementTextItem::Type + || qgi->type() == QetGraphicsTableItem::Type + || qgi->type() == TerminalStripItem::Type) return true; if(qgi->type() == QGraphicsItemGroup::Type) if(dynamic_cast(qgi)) @@ -240,6 +243,7 @@ void DiagramContent::clear() m_texts_groups.clear(); m_selected_items.clear(); m_tables.clear(); + m_terminal_strip.clear(); } /** @@ -378,7 +382,7 @@ QList DiagramContent::items(int filter) const { QList items_list; - for(QGraphicsItem *qgi : conductors(filter)) items_list << qgi; + for(auto &&qgi : conductors(filter)) items_list << qgi; if (filter & Elements) for(auto qgi : m_elements) items_list << qgi; if (filter & TextFields) for(auto qgi : m_text_fields) items_list << qgi; @@ -387,9 +391,10 @@ QList DiagramContent::items(int filter) const if (filter & ElementTextFields) for(auto qgi : m_element_texts) items_list << qgi; if (filter & TextGroup) for(auto qgi : m_texts_groups) items_list << qgi; if (filter & Tables) for(auto qgi : m_tables) items_list << qgi; + if (filter & TerminalStrip) for(const auto qgi : qAsConst(m_terminal_strip)) items_list << qgi; if (filter & SelectedOnly) { - for(QGraphicsItem *qgi : items_list) { + for(const auto &qgi : qAsConst(items_list)) { if (!qgi -> isSelected()) items_list.removeOne(qgi); } } @@ -415,6 +420,7 @@ int DiagramContent::count(int filter) const if (filter & ElementTextFields) for(auto deti : m_element_texts) { if (deti -> isSelected()) ++ count; } if (filter & TextGroup) for(auto etig : m_texts_groups) { if (etig -> isSelected()) ++ count; } if (filter & Tables) for(auto table : m_tables) { if (table -> isSelected()) ++ count; } + if (filter & TerminalStrip) for(const auto &strip : qAsConst(m_terminal_strip)) {if (strip->isSelected()) ++ count;} } else { if (filter & Elements) count += m_elements.count(); @@ -427,6 +433,7 @@ int DiagramContent::count(int filter) const if (filter & ElementTextFields) count += m_element_texts.count(); if (filter & TextGroup) count += m_texts_groups.count(); if (filter & Tables) count += m_tables.count(); + if (filter & TerminalStrip) count += m_terminal_strip.count(); } return(count); } @@ -447,7 +454,7 @@ QString DiagramContent::sentence(int filter) const int shapes_count = (filter & Shapes) ? m_shapes.count() : 0; int elmt_text_count = (filter & ElementTextFields) ? m_element_texts.count() : 0; int tables_count = (filter & Tables) ? m_tables.count() : 0; - + const int strip_count = (filter & TerminalStrip) ? m_terminal_strip.count() : 0; return( QET::ElementsAndConductorsSentence( elements_count, @@ -456,7 +463,8 @@ QString DiagramContent::sentence(int filter) const images_count, shapes_count, elmt_text_count, - tables_count + tables_count, + strip_count ) ); } diff --git a/sources/diagramcontent.h b/sources/diagramcontent.h index 76d36ace7..40105e44e 100644 --- a/sources/diagramcontent.h +++ b/sources/diagramcontent.h @@ -32,6 +32,7 @@ class ElementTextItemGroup; class Diagram; class DiagramTextItem; class QetGraphicsTableItem; +class TerminalStripItem; /** This class provides a container that makes the transmission of diagram content @@ -62,8 +63,9 @@ class DiagramContent Shapes = 128, TextGroup = 256, Tables = 512, - All = 1023, - SelectedOnly = 1024 + TerminalStrip = 1024, + All = 2047, + SelectedOnly = 2048 }; QList m_elements; @@ -78,6 +80,7 @@ class DiagramContent QSet m_texts_groups; QList m_selected_items; QVector m_tables; + QVector m_terminal_strip; QList selectedTexts() const; diff --git a/sources/elementsmover.cpp b/sources/elementsmover.cpp index c6d070ad0..11e1edaeb 100644 --- a/sources/elementsmover.cpp +++ b/sources/elementsmover.cpp @@ -171,7 +171,7 @@ void ElementsMover::endMovement() //There is only one element moved, and project authorize auto conductor, //we try auto connection of conductor; typedef DiagramContent dc; - if (m_moved_content.items(dc::TextFields | dc::Images | dc::Shapes).size() == 0 && + if (m_moved_content.items(dc::TextFields | dc::Images | dc::Shapes | dc::TerminalStrip).size() == 0 && m_moved_content.items(dc::Elements).size() == 1 && diagram_ -> project() -> autoConductor()) { diff --git a/sources/qet.cpp b/sources/qet.cpp index e7150d06e..fa07804f5 100644 --- a/sources/qet.cpp +++ b/sources/qet.cpp @@ -266,7 +266,8 @@ QString QET::ElementsAndConductorsSentence( int images_count, int shapes_count, int element_text_count, - int tables_count) + int tables_count, + int terminal_strip_count) { QString text; if (elements_count) { @@ -329,6 +330,14 @@ QString QET::ElementsAndConductorsSentence( tables_count); } + if (terminal_strip_count) { + if (!text.isEmpty()) text += ", "; + text += QObject::tr( + "%n plan de bornes", + "part of a sentence listing the content of a diagram", + terminal_strip_count); + } + return(text); } diff --git a/sources/qet.h b/sources/qet.h index 36929b2a4..b4ccfad9a 100644 --- a/sources/qet.h +++ b/sources/qet.h @@ -162,7 +162,14 @@ namespace QET { bool orthogonalProjection(const QPointF &, const QLineF &, QPointF * = nullptr); bool attributeIsAnInteger(const QDomElement &, const QString& , int * = nullptr); bool attributeIsAReal(const QDomElement &, const QString& , qreal * = nullptr); - QString ElementsAndConductorsSentence(int elements=0, int conductors=0, int indi_texts=0, int images=0, int shapes=0, int element_text=0, int tables_count=0); + QString ElementsAndConductorsSentence(int elements=0, + int conductors=0, + int indi_texts=0, + int images=0, + int shapes=0, + int element_text=0, + int tables_count=0, + int terminal_strip_count=0); QList findInDomElement(const QDomElement &, const QString &); QList findInDomElement(const QDomElement &, const QString &, const QString &); QList forbiddenCharacters(); From 9e1ef8c42f500679f6fa5e6dcf9193ba2ca3df36 Mon Sep 17 00:00:00 2001 From: joshua Date: Tue, 8 Nov 2022 22:06:50 +0100 Subject: [PATCH 05/12] Revamp code -Move MoveElementsCommand class from diagramcommands file to movegraphicsitemcommand file. -Rename the to class MoveGraphicsItemCommand. -Minor code change to make it more modern. --- sources/diagramcommands.cpp | 149 --------------- sources/diagramcommands.h | 39 ---- sources/elementsmover.cpp | 4 +- .../undocommand/movegraphicsitemcommand.cpp | 175 ++++++++++++++++++ sources/undocommand/movegraphicsitemcommand.h | 65 +++++++ 5 files changed, 242 insertions(+), 190 deletions(-) create mode 100644 sources/undocommand/movegraphicsitemcommand.cpp create mode 100644 sources/undocommand/movegraphicsitemcommand.h diff --git a/sources/diagramcommands.cpp b/sources/diagramcommands.cpp index 46e41b601..4c6b88c2f 100644 --- a/sources/diagramcommands.cpp +++ b/sources/diagramcommands.cpp @@ -148,155 +148,6 @@ CutDiagramCommand::~CutDiagramCommand() { } -/** - @brief MoveElementsCommand::MoveElementsCommand - Constructor - @param dia diagram - @param diagram_content diagram content (contain all items to be moved) - @param m movement to applied - @param parent parent undo command -*/ -MoveElementsCommand::MoveElementsCommand( - Diagram *dia, - const DiagramContent &diagram_content, - const QPointF &m, - QUndoCommand *parent -) : - QUndoCommand (parent), - diagram (dia), - content_to_move (diagram_content), - movement (m), - m_anim_group (nullptr), - first_redo (true) -{ - QString moved_content_sentence = content_to_move.sentence( - DiagramContent::Elements | - DiagramContent::TextFields | - DiagramContent::ConductorsToUpdate | - DiagramContent::ConductorsToMove | - DiagramContent::Images | - DiagramContent::Shapes | - DiagramContent::ElementTextFields | - DiagramContent::TerminalStrip - ); - - setText( - QString( - QObject::tr( - "déplacer %1", - "undo caption - %1 is a sentence listing the moved content" - ).arg(moved_content_sentence) - ) - ); -} - -/** - @brief MoveElementsCommand::~MoveElementsCommand - Destructor -*/ -MoveElementsCommand::~MoveElementsCommand() -{ - delete m_anim_group; -} - -/** - @brief MoveElementsCommand::undo -*/ -void MoveElementsCommand::undo() -{ - diagram -> showMe(); - m_anim_group->setDirection(QAnimationGroup::Forward); - m_anim_group->start(); - QUndoCommand::undo(); -} - -/** - @brief MoveElementsCommand::redo -*/ -void MoveElementsCommand::redo() -{ - diagram -> showMe(); - if (first_redo) { - first_redo = false; - move(-movement); - } - else { - m_anim_group->setDirection(QAnimationGroup::Backward); - m_anim_group->start(); - } - QUndoCommand::redo(); -} - -/** - @brief MoveElementsCommand::move - Move item and conductor to actual_movement - @param actual_movement movement to be applied -*/ -void MoveElementsCommand::move(const QPointF &actual_movement) -{ - typedef DiagramContent dc; - - //Move every movable items, except conductor - for (auto &&qgi : content_to_move.items(dc::Elements - | dc::TextFields - | dc::Images - | dc::Shapes - | dc::TextGroup - | dc::ElementTextFields - | dc::Tables - | dc::TerminalStrip)) - { - //If curent item have parent, and parent item is in content_to_move - //we don't apply movement to this item, because this item will be moved by is parent. - if (qgi->parentItem()) - if (content_to_move.items().contains(qgi->parentItem())) - continue; - - if(qgi->toGraphicsObject()) - setupAnimation(qgi->toGraphicsObject(), "pos", - qgi->pos(), qgi->pos() + actual_movement); - else if(qgi->type() == QGraphicsItemGroup::Type) - { - //ElementTextItemGroup is a QObject but not a QGraphicsObject - if(ElementTextItemGroup *etig = dynamic_cast(qgi)) - setupAnimation(etig, "pos", etig->pos(), - etig->pos() + actual_movement); - } - else qgi -> setPos(qgi->pos() + actual_movement); - } - - // Move some conductors - for (Conductor *conductor : content_to_move.m_conductors_to_move) - setupAnimation(conductor, "pos", conductor->pos(), - conductor->pos() + actual_movement); - - // Recalcul the path of other conductor - for (Conductor *conductor : content_to_move.m_conductors_to_update) - setupAnimation(conductor, "animPath", 1, 1); -} - -/** - @brief MoveElementsCommand::setupAnimation - Set up the animation for this undo command - @param target object to anim - @param propertyName property to animate - @param start value at start - @param end value at end -*/ -void MoveElementsCommand::setupAnimation(QObject *target, - const QByteArray &propertyName, - const QVariant& start, - const QVariant& end) { - //create animation group if not yet. - if (m_anim_group == nullptr) m_anim_group = new QParallelAnimationGroup(); - QPropertyAnimation *animation = new QPropertyAnimation(target, propertyName); - animation->setDuration(300); - animation->setStartValue(start); - animation->setEndValue(end); - animation->setEasingCurve(QEasingCurve::OutQuad); - m_anim_group->addAnimation(animation); -} - /** @brief MoveConductorsTextsCommand::MoveConductorsTextsCommand Constructeur diff --git a/sources/diagramcommands.h b/sources/diagramcommands.h index 94baea5ff..c869eb552 100644 --- a/sources/diagramcommands.h +++ b/sources/diagramcommands.h @@ -69,45 +69,6 @@ class CutDiagramCommand : public DeleteQGraphicsItemCommand { CutDiagramCommand(const CutDiagramCommand &); }; -/** - @brief The MoveElementsCommand class - This command moves some content on a particular diagram. -*/ -class MoveElementsCommand : public QUndoCommand { - // constructors, destructor - public: - MoveElementsCommand(Diagram *, const DiagramContent &, - const QPointF &m, QUndoCommand * = nullptr); - ~MoveElementsCommand() override; - private: - MoveElementsCommand(const MoveElementsCommand &); - - // methods - public: - void undo() override; - void redo() override; - virtual void move(const QPointF &); - - private: - void setupAnimation (QObject * target, - const QByteArray &propertyName, - const QVariant& start, - const QVariant& end); - - // attributes - private: - /// diagram the movement takes place on. - Diagram *diagram; - /// moved content - DiagramContent content_to_move; - /// applied movement - QPointF movement; - ///animation group - QParallelAnimationGroup *m_anim_group; - /// prevent the first call to redo() - bool first_redo; -}; - /** @brief The MoveConductorsTextsCommand class This command moves text items related to conductors diff --git a/sources/elementsmover.cpp b/sources/elementsmover.cpp index 11e1edaeb..bd41cc319 100644 --- a/sources/elementsmover.cpp +++ b/sources/elementsmover.cpp @@ -20,7 +20,6 @@ #include "conductorautonumerotation.h" #include "diagram.h" #include "qetgraphicsitem/conductor.h" -#include "diagramcommands.h" #include "qetgraphicsitem/conductortextitem.h" #include "qetgraphicsitem/diagramimageitem.h" #include "qetgraphicsitem/dynamicelementtextitem.h" @@ -28,6 +27,7 @@ #include "qetgraphicsitem/elementtextitemgroup.h" #include "qetgraphicsitem/independenttextitem.h" #include "undocommand/addgraphicsobjectcommand.h" +#include "undocommand/movegraphicsitemcommand.h" /** @brief ElementsMover::ElementsMover Constructor @@ -164,7 +164,7 @@ void ElementsMover::endMovement() //Create undo move if there is a movement if (!current_movement_.isNull()) { - QUndoCommand *quc = new MoveElementsCommand(diagram_, m_moved_content, current_movement_, undo_object); + QUndoCommand *quc = new MoveGraphicsItemCommand(diagram_, m_moved_content, current_movement_, undo_object); undo_object->setText(quc->text()); } diff --git a/sources/undocommand/movegraphicsitemcommand.cpp b/sources/undocommand/movegraphicsitemcommand.cpp new file mode 100644 index 000000000..33dd89b7e --- /dev/null +++ b/sources/undocommand/movegraphicsitemcommand.cpp @@ -0,0 +1,175 @@ +/* + 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 +#include + +#include "movegraphicsitemcommand.h" + +#include "../qetgraphicsitem/conductor.h" +#include "../qetgraphicsitem/elementtextitemgroup.h" + +#include "../diagram.h" + +/** + * @brief MoveGraphicsItemCommand::MoveGraphicsItemCommand + * @param diagram : Diagram where the movement occur + * @param content : content aka QGraphicsItem to move + * @param movement : the movement to apply + * @param parent : parent undo command + */ +MoveGraphicsItemCommand::MoveGraphicsItemCommand(Diagram *diagram, + const DiagramContent &content, + const QPointF &movement, + QUndoCommand *parent) : + QUndoCommand{parent}, + m_diagram{diagram}, + m_content{content}, + m_movement{movement} +{ + const auto moved_content_sentence = m_content.sentence(DiagramContent::Elements + | DiagramContent::TextFields + | DiagramContent::ConductorsToUpdate + | DiagramContent::ConductorsToMove + | DiagramContent::Images + | DiagramContent::Shapes + | DiagramContent::ElementTextFields + | DiagramContent::TerminalStrip); + + setText(QString(QObject::tr("déplacer %1", + "undo caption - %1 is a sentence listing the moved content").arg(moved_content_sentence))); +} + +/** + * @brief MoveGraphicsItemCommand::undo + * Reimplemented from QUndoCommand::undo() + */ +void MoveGraphicsItemCommand::undo() +{ + if (m_diagram) + { + m_diagram->showMe(); + m_anim_group.setDirection(QAnimationGroup::Forward); + m_anim_group.start(); + } + QUndoCommand::undo(); +} + +/** + * @brief MoveGraphicsItemCommand::redo + * Reimplemented from QUndoCommand::redo() + */ +void MoveGraphicsItemCommand::redo() +{ + if (m_diagram) + { + m_diagram->showMe(); + if (m_first_redo) + { + m_first_redo = false; + move(-m_movement); + } + else + { + m_anim_group.setDirection(QAnimationGroup::Backward); + m_anim_group.start(); + } + } + QUndoCommand::redo(); +} + +/** + * @brief MoveGraphicsItemCommand::move + * Apply @a movement to items of m_content + * @param movement + */ +void MoveGraphicsItemCommand::move(const QPointF &movement) +{ + for (auto &&qgi : m_content.items(DiagramContent::Elements + | DiagramContent::TextFields + | DiagramContent::Images + | DiagramContent::Shapes + | DiagramContent::TextGroup + | DiagramContent::ElementTextFields + | DiagramContent::Tables + | DiagramContent::TerminalStrip)) + { + //If item have a parent and the parent is in m_content, + //we don't apply movement because this item will be moved by his parent + if (const auto parent_ = qgi->parentItem()) { + if (m_content.items().contains(parent_)) { + continue; + } + } + + if (const auto graphics_object = qgi->toGraphicsObject()) { + setupAnimation(graphics_object, + "pos", + graphics_object->pos(), + graphics_object->pos() + movement); + } + else if (qgi->type() == QGraphicsItemGroup::Type) + { + //ElementTextItemGroup is a QObject not a QGraphicsObject + if (ElementTextItemGroup *etig = dynamic_cast(qgi)) { + setupAnimation(etig, + "pos", + etig->pos(), + etig->pos() + movement); + } + } + else + { + qgi->setPos(qgi->pos() + movement); + } + } + + //Move some conductors + for (const auto &conductor : qAsConst(m_content.m_conductors_to_move)) { + setupAnimation(conductor, + "pos", + conductor->pos(), + conductor->pos() + movement); + } + + //Recalcul the path of other conductors + for (const auto &conductor : qAsConst(m_content.m_conductors_to_update)) { + setupAnimation(conductor, "animPath", 1, 1); + } +} + +/** + * @brief MoveGraphicsItemCommand::setupAnimation + * Create the animation used for the movement. + * @see QPropertyAnimation. + * @param target + * @param property_name + * @param start + * @param end + */ +void MoveGraphicsItemCommand::setupAnimation(QObject *target, + const QByteArray &property_name, + const QVariant &start, + const QVariant &end) +{ + QPropertyAnimation *animation{new QPropertyAnimation(target, property_name)}; + animation->setDuration(300); + animation->setStartValue(start); + animation->setEndValue(end); + animation->setEasingCurve(QEasingCurve::OutQuad); + m_anim_group.addAnimation(animation); +} diff --git a/sources/undocommand/movegraphicsitemcommand.h b/sources/undocommand/movegraphicsitemcommand.h new file mode 100644 index 000000000..6b5722f59 --- /dev/null +++ b/sources/undocommand/movegraphicsitemcommand.h @@ -0,0 +1,65 @@ +/* + 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 MOVEGRAPHICSITEMCOMMAND_H +#define MOVEGRAPHICSITEMCOMMAND_H + +#include +#include +#include + +#include "../diagramcontent.h" + +class Diagram; + +/** + * @brief The MoveGraphicsItemCommand class + * An undo command used for move item(s) in a diagram + */ +class MoveGraphicsItemCommand : public QUndoCommand +{ + public: + MoveGraphicsItemCommand(Diagram *diagram, + const DiagramContent &content, + const QPointF &movement, + QUndoCommand *parent = nullptr); + + ~MoveGraphicsItemCommand() {} + + private: + MoveGraphicsItemCommand(const MoveGraphicsItemCommand &); + + public: + void undo() override; + void redo() override; + + private: + void move(const QPointF &movement); + void setupAnimation(QObject *target, + const QByteArray &property_name, + const QVariant &start, + const QVariant &end); + + private: + QPointer m_diagram; + DiagramContent m_content; + const QPointF m_movement; + QParallelAnimationGroup m_anim_group; + bool m_first_redo{true}; +}; + +#endif // MOVEGRAPHICSITEMCOMMAND_H From aca3b8ad1e7d1f0d0f0925da836e3c8c8addd002 Mon Sep 17 00:00:00 2001 From: joshua Date: Mon, 14 Nov 2022 21:10:38 +0100 Subject: [PATCH 06/12] Minor : corrects a minor aesthetic defect when unbridge terminals --- .../UndoCommand/bridgeterminalscommand.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.cpp b/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.cpp index 1a1eec5ba..6ccce15b0 100644 --- a/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.cpp +++ b/sources/TerminalStrip/UndoCommand/bridgeterminalscommand.cpp @@ -16,6 +16,7 @@ along with QElectroTech. If not, see . */ #include "bridgeterminalscommand.h" +#include "../terminalstripbridge.h" BridgeTerminalsCommand::BridgeTerminalsCommand(TerminalStrip *strip, QVector> real_terminal, @@ -57,8 +58,18 @@ UnBridgeTerminalsCommand::UnBridgeTerminalsCommand(TerminalStrip *strip, if (strip->canUnBridge(real_terminal)) { - m_terminals = real_terminal; - m_bridge = strip->isBridged(real_terminal.first()); + m_bridge = strip->isBridged(real_terminal.first()); + + //If bridge have one more terminals than @real_terminal + //that mean every terminals of the bridge must be unbridged by this undo command, + //else the single terminal who's not umbridged by this undo command + //continue to have a bridge (to nothing) and this nowhere bridge is visible + //in the terminal strip graphic item and terminal strip editor dialog. + if (m_bridge->realTerminals().size() == real_terminal.size() + 1) { + m_terminals = m_bridge->realTerminals(); + } else { + m_terminals = real_terminal; + } } } From a18cd2461f7b9037a3ab0235dbfed93f26af2003 Mon Sep 17 00:00:00 2001 From: joshua Date: Mon, 14 Nov 2022 21:51:14 +0100 Subject: [PATCH 07/12] Minor change about checkable QAction of QetDiagramEditor --- sources/qetdiagrameditor.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index db362aa0b..18376d12d 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -675,17 +675,20 @@ void QETDiagramEditor::setUpActions() add_polyline ->setStatusTip(tr("Ajoute une polyligne sur le folio actuel")); add_terminal_strip->setStatusTip(tr("Ajoute un plan de bornier sur le folio actuel")); - add_text ->setData("text"); - add_image ->setData("image"); - add_line ->setData("line"); - add_rectangle->setData("rectangle"); - add_ellipse ->setData("ellipse"); - add_polyline ->setData("polyline"); + add_text ->setData(QStringLiteral("text")); + add_image ->setData(QStringLiteral("image")); + add_line ->setData(QStringLiteral("line")); + add_rectangle->setData(QStringLiteral("rectangle")); + add_ellipse ->setData(QStringLiteral("ellipse")); + add_polyline ->setData(QStringLiteral("polyline")); add_terminal_strip->setData(QStringLiteral("terminal_strip")); - for(QAction *action : m_add_item_actions_group.actions()) { - action->setCheckable(true); - } + add_text->setCheckable(true); + add_line->setCheckable(true); + add_rectangle->setCheckable(true); + add_ellipse->setCheckable(true); + add_polyline->setCheckable(true); + connect(&m_add_item_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::addItemGroupTriggered); //Depth action @@ -1427,7 +1430,6 @@ void QETDiagramEditor::addItemGroupTriggered(QAction *action) if (deai->isNull()) { delete deai; - action->setChecked(false); return; } else From 81640015e5c5a011de84aa6e92a5a680e940376e Mon Sep 17 00:00:00 2001 From: joshua Date: Fri, 2 Dec 2022 18:12:47 +0100 Subject: [PATCH 08/12] Double click a TerminalStripItem open the editor --- .../GraphicsItem/terminalstripitem.cpp | 11 +++++- .../GraphicsItem/terminalstripitem.h | 2 + .../ui/terminalstripeditorwindow.cpp | 20 +++++++++- .../ui/terminalstripeditorwindow.h | 37 ++++++++++++++++++- sources/qetapp.cpp | 25 ++++++++++++- sources/qetapp.h | 3 +- sources/qetdiagrameditor.cpp | 3 +- 7 files changed, 93 insertions(+), 8 deletions(-) diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp b/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp index 8b4ebf94c..86427d307 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp +++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp @@ -17,6 +17,8 @@ */ #include "terminalstripitem.h" #include "../../qetgraphicsitem/qgraphicsitemutility.h" +#include "../terminalstrip.h" +#include "../ui/terminalstripeditorwindow.h" TerminalStripItem::TerminalStripItem(QPointer strip, QGraphicsItem *parent) : QetGraphicsItem{parent}, @@ -53,5 +55,12 @@ QRectF TerminalStripItem::boundingRect() const * @return usual name of this item */ QString TerminalStripItem::name() const { - return tr("plan de bornes"); + return tr("plan de bornes"); +} + +void TerminalStripItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED (event); + + TerminalStripEditorWindow::edit(m_strip); } diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h index 1fbb4f22c..78343c423 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h +++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h @@ -39,6 +39,8 @@ class TerminalStripItem : public QetGraphicsItem QRectF boundingRect() const override; QString name() const override; + void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override; + private: QPointer m_strip; TerminalStripDrawer m_drawer; diff --git a/sources/TerminalStrip/ui/terminalstripeditorwindow.cpp b/sources/TerminalStrip/ui/terminalstripeditorwindow.cpp index 425eef77b..b60933c5c 100644 --- a/sources/TerminalStrip/ui/terminalstripeditorwindow.cpp +++ b/sources/TerminalStrip/ui/terminalstripeditorwindow.cpp @@ -19,6 +19,8 @@ #include "../UndoCommand/addterminalstripcommand.h" #include "freeterminaleditor.h" +#include "../../qetapp.h" +#include "../../qetdiagrameditor.h" #include "../../qetproject.h" #include "../realterminal.h" #include "../terminalstrip.h" @@ -27,6 +29,8 @@ #include "terminalstripeditorwindow.h" #include "terminalstriptreedockwidget.h" +QPointer TerminalStripEditorWindow::window_; + static const int EMPTY_PAGE = 0; static const int FREE_TERMINAL_PAGE = 1; static const int TERMINAL_STRIP_PAGE = 2; @@ -35,6 +39,16 @@ static const int TERMINAL_STRIP_PAGE = 2; * @param project * @param parent */ +void TerminalStripEditorWindow::edit(TerminalStrip *strip) +{ + if (const auto project_ = strip->project()) + { + auto editor_ = TerminalStripEditorWindow::instance(project_, QETApp::diagramEditor(project_)); + editor_->setCurrentStrip(strip); + editor_->show(); + } +} + TerminalStripEditorWindow::TerminalStripEditorWindow(QETProject *project, QWidget *parent) : QMainWindow(parent), ui(new Ui::TerminalStripEditorWindow), @@ -59,7 +73,11 @@ TerminalStripEditorWindow::TerminalStripEditorWindow(QETProject *project, QWidge */ TerminalStripEditorWindow::~TerminalStripEditorWindow() { - delete ui; + delete ui; +} + +void TerminalStripEditorWindow::setCurrentStrip(TerminalStrip *strip) { + m_tree_dock->setSelectedStrip(strip); } /** diff --git a/sources/TerminalStrip/ui/terminalstripeditorwindow.h b/sources/TerminalStrip/ui/terminalstripeditorwindow.h index a31b709c0..65ab72bf6 100644 --- a/sources/TerminalStrip/ui/terminalstripeditorwindow.h +++ b/sources/TerminalStrip/ui/terminalstripeditorwindow.h @@ -19,6 +19,8 @@ #define TERMINALSTRIPEDITORWINDOW_H #include +#include +#include class QETProject; class TerminalStripTreeDockWidget; @@ -35,16 +37,47 @@ class TerminalStripEditorWindow : public QMainWindow { Q_OBJECT - public: + private: + //We need to use a QPointer instead of a raw pointer because when window_ + //have got a parent widget, the parent widget can delete the window_ + //instance in her destrucor and then window_ become a dangling pointer. + static QPointer window_; + + public: + static TerminalStripEditorWindow* instance(QETProject *project, QWidget *parent = nullptr) { + static QMutex mutex_; + if (!window_) { + mutex_.lock(); + if (!window_) + window_ = new TerminalStripEditorWindow{project, parent}; + mutex_.unlock(); + } + return window_; + } + + static void dropInstance () { + static QMutex mutex; + if (window_) { + mutex.lock(); + window_->deleteLater(); + window_.clear(); + mutex.unlock(); + } + } + + static void edit(TerminalStrip *strip); + + public: explicit TerminalStripEditorWindow(QETProject *project, QWidget *parent = nullptr); ~TerminalStripEditorWindow(); + void setCurrentStrip(TerminalStrip *strip); + private slots: void on_m_add_terminal_strip_triggered(); void on_m_remove_terminal_triggered(); void on_m_reload_triggered(); void on_m_button_box_clicked(QAbstractButton *button); - void on_m_stacked_widget_currentChanged(int arg1); private: diff --git a/sources/qetapp.cpp b/sources/qetapp.cpp index 481b16b48..132081e8b 100644 --- a/sources/qetapp.cpp +++ b/sources/qetapp.cpp @@ -36,6 +36,7 @@ #include "ui/aboutqetdialog.h" #include "ui/configpage/generalconfigurationpage.h" #include "machine_info.h" +#include "TerminalStrip/ui/terminalstripeditorwindow.h" #include #include @@ -159,6 +160,7 @@ QETApp::~QETApp() ElementFactory::dropInstance(); ElementPictureFactory::dropInstance(); MachineInfo::dropInstance(); + TerminalStripEditorWindow::dropInstance(); } @@ -1128,7 +1130,28 @@ QFont QETApp::indiTextsItemFont(qreal size) */ QList QETApp::diagramEditors() { - return(QETApp::instance() -> detectWindows()); + return(QETApp::instance() -> detectWindows()); +} + +/** + * @brief QETApp::diagramEditor + * @param project + * @return The diagram editor of @a project or nullptr. + */ +QETDiagramEditor *QETApp::diagramEditor(QETProject *project) +{ + for (const auto &editor : QETApp::instance()->detectWindows()) + { + for (const auto &project_view : editor->openedProjects()) + { + if (project_view->project() == project) + { + return editor; + } + } + } + + return nullptr; } /** diff --git a/sources/qetapp.h b/sources/qetapp.h index 6ef57d71e..186b30f94 100644 --- a/sources/qetapp.h +++ b/sources/qetapp.h @@ -148,7 +148,8 @@ class QETApp : public QObject static QFont indiTextsItemFont (qreal = -1.0); static QETDiagramEditor *diagramEditorForFile(const QString &); static QETDiagramEditor *diagramEditorAncestorOf (const QWidget *child); - static QList diagramEditors(); + static QList diagramEditors(); + static QETDiagramEditor* diagramEditor(QETProject *project); static QList elementEditors(); static QList elementEditors(QETProject *); static QList titleBlockTemplateEditors(); diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index 18376d12d..a61192701 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -447,8 +447,7 @@ void QETDiagramEditor::setUpActions() { if (auto project = this->currentProject()) { - auto tsew {new TerminalStripEditorWindow{project, this}}; - tsew->show(); + TerminalStripEditorWindow::instance(project, this)->show(); } }); From d23a5bbdc799f466bb1b0bedacf8a5fe1b68dd58 Mon Sep 17 00:00:00 2001 From: joshua Date: Fri, 2 Dec 2022 18:26:56 +0100 Subject: [PATCH 09/12] Fix wrong use of QStringLiteral and QLatin1String --- sources/TerminalStrip/terminalstrip.cpp | 2 +- sources/TerminalStrip/terminalstripdata.cpp | 22 +++++++++---------- .../TerminalStrip/ui/freeterminalmodel.cpp | 4 ++-- .../TerminalStrip/ui/terminalstripmodel.cpp | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sources/TerminalStrip/terminalstrip.cpp b/sources/TerminalStrip/terminalstrip.cpp index 629cd7be9..ba943b34d 100644 --- a/sources/TerminalStrip/terminalstrip.cpp +++ b/sources/TerminalStrip/terminalstrip.cpp @@ -976,7 +976,7 @@ QDomElement TerminalStrip::toXml(QDomDocument &parent_document) root_elmt.appendChild(m_data.toXml(parent_document)); //Undrawed terminals - auto xml_layout = parent_document.createElement("layout"); + auto xml_layout = parent_document.createElement(QStringLiteral("layout")); for (auto &phy_t : m_physical_terminals) { xml_layout.appendChild(phy_t->toXml(parent_document)); } diff --git a/sources/TerminalStrip/terminalstripdata.cpp b/sources/TerminalStrip/terminalstripdata.cpp index bd86b1a14..78d740ee3 100644 --- a/sources/TerminalStrip/terminalstripdata.cpp +++ b/sources/TerminalStrip/terminalstripdata.cpp @@ -34,7 +34,7 @@ QDomElement TerminalStripData::toXml(QDomDocument &xml_document) const root_elmt.setAttribute(QStringLiteral("uuid"), m_uuid.toString()); - auto info_elmt = xml_document.createElement("informations"); + auto info_elmt = xml_document.createElement(QStringLiteral("informations")); root_elmt.appendChild(info_elmt); if (!m_installation.isEmpty()) { @@ -65,23 +65,23 @@ bool TerminalStripData::fromXml(const QDomElement &xml_element) return false; } #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) - m_uuid = QUuid::fromString(xml_element.attribute(QLatin1String("uuid"))); + m_uuid = QUuid::fromString(xml_element.attribute(QStringLiteral("uuid"))); #else m_uuid = QUuid(xml_element.attribute(QStringLiteral("uuid"))); #endif for (auto &xml_info : - QETXML::findInDomElement(xml_element.firstChildElement("informations"), - QStringLiteral("information"))) + QETXML::findInDomElement(xml_element.firstChildElement(QStringLiteral("informations")), + QStringLiteral("information"))) { - auto name = xml_info.attribute("name"); + auto name = xml_info.attribute(QStringLiteral("name")); auto value = xml_info.text(); - if (name == QStringLiteral("installation")) { m_installation = value;} - else if (name == QStringLiteral("location")) {m_location = value;} - else if (name == QStringLiteral("name")) {m_name = value;} - else if (name == QStringLiteral("comment")) {m_comment = value;} - else if (name == QStringLiteral("description")) {m_description = value;} + if (name == QLatin1String("installation")) { m_installation = value;} + else if (name == QLatin1String("location")) {m_location = value;} + else if (name == QLatin1String("name")) {m_name = value;} + else if (name == QLatin1String("comment")) {m_comment = value;} + else if (name == QLatin1String("description")) {m_description = value;} } return true; @@ -101,7 +101,7 @@ TerminalStripData &TerminalStripData::operator=(const TerminalStripData &other) QDomElement TerminalStripData::infoToXml(QDomDocument &xml_doc, const QString &name, const QString &value) { - auto xml_elmt = xml_doc.createElement("information"); + auto xml_elmt = xml_doc.createElement(QStringLiteral("information")); xml_elmt.setAttribute(QStringLiteral("name"), name); xml_elmt.appendChild(xml_doc.createTextNode(value)); diff --git a/sources/TerminalStrip/ui/freeterminalmodel.cpp b/sources/TerminalStrip/ui/freeterminalmodel.cpp index 4bd5f241b..33b782900 100644 --- a/sources/TerminalStrip/ui/freeterminalmodel.cpp +++ b/sources/TerminalStrip/ui/freeterminalmodel.cpp @@ -333,7 +333,7 @@ QWidget *FreeTerminalModelDelegate::createEditor(QWidget *parent, const QStyleOp { if (index.column() == TYPE_CELL) { auto qcb = new QComboBox(parent); - qcb->setObjectName(QLatin1String("terminal_type")); + qcb->setObjectName(QStringLiteral("terminal_type")); qcb->addItem(ElementData::translatedTerminalType(ElementData::TTGeneric), ElementData::TTGeneric); qcb->addItem(ElementData::translatedTerminalType(ElementData::TTFuse), ElementData::TTFuse); qcb->addItem(ElementData::translatedTerminalType(ElementData::TTSectional), ElementData::TTSectional); @@ -344,7 +344,7 @@ QWidget *FreeTerminalModelDelegate::createEditor(QWidget *parent, const QStyleOp } if (index.column() == FUNCTION_CELL) { auto qcb = new QComboBox(parent); - qcb->setObjectName(QLatin1String("terminal_function")); + qcb->setObjectName(QStringLiteral("terminal_function")); qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFGeneric), ElementData::TFGeneric); qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFPhase), ElementData::TFPhase); qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFNeutral), ElementData::TFNeutral); diff --git a/sources/TerminalStrip/ui/terminalstripmodel.cpp b/sources/TerminalStrip/ui/terminalstripmodel.cpp index fe37ea7da..2ca4f7ef7 100644 --- a/sources/TerminalStrip/ui/terminalstripmodel.cpp +++ b/sources/TerminalStrip/ui/terminalstripmodel.cpp @@ -794,7 +794,7 @@ QWidget *TerminalStripModelDelegate::createEditor(QWidget *parent, const QStyleO { if (index.column() == TYPE_CELL) { auto qcb = new QComboBox(parent); - qcb->setObjectName(QLatin1String("terminal_type")); + qcb->setObjectName(QStringLiteral("terminal_type")); qcb->addItem(ElementData::translatedTerminalType(ElementData::TTGeneric), ElementData::TTGeneric); qcb->addItem(ElementData::translatedTerminalType(ElementData::TTFuse), ElementData::TTFuse); qcb->addItem(ElementData::translatedTerminalType(ElementData::TTSectional), ElementData::TTSectional); @@ -805,7 +805,7 @@ QWidget *TerminalStripModelDelegate::createEditor(QWidget *parent, const QStyleO } if (index.column() == FUNCTION_CELL) { auto qcb = new QComboBox(parent); - qcb->setObjectName(QLatin1String("terminal_function")); + qcb->setObjectName(QStringLiteral("terminal_function")); qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFGeneric), ElementData::TFGeneric); qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFPhase), ElementData::TFPhase); qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFNeutral), ElementData::TFNeutral); From 1f99a40f1b16f476d2bb5391bb3956a9511e24ca Mon Sep 17 00:00:00 2001 From: joshua Date: Fri, 2 Dec 2022 19:35:17 +0100 Subject: [PATCH 10/12] Move terminal strip drawer class in is own file --- .../GraphicsItem/terminalstripdrawer.cpp | 226 ++++++++++++ .../GraphicsItem/terminalstripdrawer.h | 45 +++ .../GraphicsItem/terminalstripitem.h | 2 +- .../terminalstriplayoutpattern.cpp | 345 +++++++++--------- .../GraphicsItem/terminalstriplayoutpattern.h | 32 +- 5 files changed, 461 insertions(+), 189 deletions(-) create mode 100644 sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp create mode 100644 sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp new file mode 100644 index 000000000..b1c011c09 --- /dev/null +++ b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp @@ -0,0 +1,226 @@ +/* + 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 "terminalstripdrawer.h" +#include + +#include "../physicalterminal.h" +#include "../realterminal.h" +#include "../terminalstrip.h" +#include "../terminalstripbridge.h" + +/** + * @brief TerminalStripDrawer::TerminalStripDrawer + * @param strip + * @param pattern + */ +TerminalStripDrawer::TerminalStripDrawer(QPointer strip) : + m_strip(strip) +{} + +/** + * @brief TerminalStripDrawer::paint + * @param painter + */ +void TerminalStripDrawer::paint(QPainter *painter) +{ + if (m_strip) + { + //To draw text, QPainter need a Qrect. Instead of create an instance + //for each text, we re-use the same instance of QRect. + QRect text_rect; + painter->save(); + + auto pen_{painter->pen()}; + pen_.setColor(Qt::black); + pen_.setWidth(1); + + auto brush_ = painter->brush(); + brush_.setColor(Qt::white); + + painter->setPen(pen_); + painter->setBrush(brush_); + + //Draw header + painter->drawRect(m_pattern.m_header_rect); + + //Draw the header text + painter->save(); + + if (m_pattern.m_header_text_orientation == Qt::Horizontal) + { + text_rect.setRect(0,m_pattern.m_header_rect.y(),m_pattern.m_header_rect.width(),m_pattern.m_header_rect.height()); + } + else + { + painter->translate(m_pattern.m_header_rect.bottomLeft()); + painter->rotate(270); + text_rect.setRect(0,0,m_pattern.m_header_rect.height(),m_pattern.m_header_rect.width()); + } + + const auto text_{m_strip->installation() + " " + m_strip->location() + " " + m_strip->name()}; + painter->drawText(text_rect, text_, m_pattern.headerTextOption()); + painter->restore(); + + //Move painter pos to next drawing + painter->translate(m_pattern.m_header_rect.width(),0); + + int x_offset{m_pattern.m_header_rect.width()}; + + //Draw spacer + painter->drawRect(m_pattern.m_spacer_rect); + //Move painter pos to next drawing + painter->translate(m_pattern.m_spacer_rect.width(),0); + x_offset += m_pattern.m_spacer_rect.width(); + + + //Draw terminals + const auto terminals_text_rect{m_pattern.m_terminals_text_rect}; + const auto terminals_text_orientation{m_pattern.m_terminals_text_orientation}; + const auto terminals_text_option{m_pattern.terminalsTextOption()}; + QRect terminal_rect; + + QHash> bridges_anchor_points; + + //Loop over physical terminals + for (const auto &physical_t : m_strip->physicalTerminal()) + { + //Get the good offset according to how many level have the current physical terminal + const QVector> real_terminal{physical_t->realTerminals()}; + const auto real_t_count{real_terminal.size()}; + const auto offset_{4 - real_t_count}; + + //Loop over real terminals + for (auto i=0 ; i= 4) { + break; + } + + terminal_rect = m_pattern.m_terminal_rect[index_]; + //Draw terminal rect + painter->drawRect(terminal_rect); + + //Draw text + painter->save(); + if (terminals_text_orientation[index_] == Qt::Horizontal) + { + text_rect = terminals_text_rect[index_]; + } + else + { + const auto rect_{terminals_text_rect[index_]}; + painter->translate(rect_.bottomLeft()); + painter->rotate(270); + text_rect.setRect(0, 0, rect_.height(), rect_.width()); + } + + const auto shared_real_terminal{real_terminal[i]}; + painter->drawText(text_rect, + shared_real_terminal ? shared_real_terminal->label() : QLatin1String(), + terminals_text_option[index_]); + painter->restore(); + + //Add bridge anchor + if (shared_real_terminal->isBridged()) + { + painter->save(); + if (const auto bridge_ = shared_real_terminal->bridge()) + { + const auto anchor_center{m_pattern.m_bridge_point_d/2}; + painter->setBrush(Qt::SolidPattern); + painter->drawEllipse(QPointF{terminal_rect.width()/2, m_pattern.m_bridge_point_y_offset[index_]}, + anchor_center, + anchor_center); + + auto anchor_points{bridges_anchor_points.value(bridge_->uuid())}; + anchor_points.append(QPointF{x_offset + terminal_rect.width()/2, + m_pattern.m_bridge_point_y_offset[index_]}); + bridges_anchor_points.insert(bridge_->uuid(), anchor_points); + } + painter->restore(); + } + + //Move painter pos to next drawing + painter->translate(terminal_rect.width(),0); + x_offset += terminal_rect.width(); + } + } + + painter->restore(); + + //Draw the bridges + for (const auto &points_ : qAsConst(bridges_anchor_points)) + { + painter->save(); + auto pen_{painter->pen()}; + pen_.setWidth(2); + painter->setPen(pen_); + painter->drawPolyline(QPolygonF{points_}); + painter->restore(); + } + } +} + +QRectF TerminalStripDrawer::boundingRect() const +{ + return QRect{0, 0, width(), height()};; +} + +int TerminalStripDrawer::height() const +{ + auto height_{m_pattern.m_header_rect.y() + m_pattern.m_header_rect.height()}; + + height_ = std::max(height_, m_pattern.m_spacer_rect.y() + m_pattern.m_spacer_rect.height()); + + for (const auto &rect : m_pattern.m_terminal_rect) { + height_ = std::max(height_, rect.y() + rect.height()); + } + + return height_; +} + +int TerminalStripDrawer::width() const +{ + int width_{m_pattern.m_header_rect.width() + m_pattern.m_spacer_rect.width()}; + + if (m_strip) + { + //Loop over physical terminals + for (const auto &physical_t : m_strip->physicalTerminal()) + { + //Get the good offset according to how many level have the current physical terminal + const QVector> real_terminal{physical_t->realTerminals()}; + const auto real_t_count{real_terminal.size()}; + const auto offset_{4 - real_t_count}; + + //Loop over real terminals + for (auto i=0 ; i= 4) { + break; + } + + width_ += m_pattern.m_terminal_rect[index_].width(); + } + } + } + + return width_; +} diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h new file mode 100644 index 000000000..c59e5f8e4 --- /dev/null +++ b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h @@ -0,0 +1,45 @@ +/* + 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 TERMINALSTRIPDRAWER_H +#define TERMINALSTRIPDRAWER_H + +#include + +#include "terminalstriplayoutpattern.h" + +class QPainter; +class TerminalStrip; + +class TerminalStripDrawer +{ + public: + TerminalStripDrawer(QPointer strip); + void paint(QPainter *painter); + + QRectF boundingRect() const; + + private: + int height() const; + int width() const; + + private: + QPointer m_strip; + TerminalStripLayoutPattern m_pattern; +}; + +#endif // TERMINALSTRIPDRAWER_H diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h index 78343c423..4a8371592 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h +++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h @@ -20,7 +20,7 @@ #include -#include "terminalstriplayoutpattern.h" +#include "terminalstripdrawer.h" #include "../../qetgraphicsitem/qetgraphicsitem.h" class TerminalStrip; diff --git a/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp b/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp index c10c2e1e5..2df7976d5 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp +++ b/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp @@ -16,215 +16,216 @@ along with QElectroTech. If not, see . */ #include "terminalstriplayoutpattern.h" +#include -#include "../physicalterminal.h" -#include "../realterminal.h" -#include "../terminalstrip.h" -#include "../terminalstripbridge.h" +//#include "../physicalterminal.h" +//#include "../realterminal.h" +//#include "../terminalstrip.h" +//#include "../terminalstripbridge.h" -#include +//#include -/** - * @brief TerminalStripDrawer::TerminalStripDrawer - * @param strip - * @param pattern - */ -TerminalStripDrawer::TerminalStripDrawer(QPointer strip) : - m_strip(strip) -{} +///** +// * @brief TerminalStripDrawer::TerminalStripDrawer +// * @param strip +// * @param pattern +// */ +//TerminalStripDrawer::TerminalStripDrawer(QPointer strip) : +// m_strip(strip) +//{} -/** - * @brief TerminalStripDrawer::paint - * @param painter - */ -void TerminalStripDrawer::paint(QPainter *painter) -{ - if (m_strip) - { - //To draw text, QPainter need a Qrect. Instead of create an instance - //for each text, we re-use the same instance of QRect. - QRect text_rect; - painter->save(); +///** +// * @brief TerminalStripDrawer::paint +// * @param painter +// */ +//void TerminalStripDrawer::paint(QPainter *painter) +//{ +// if (m_strip) +// { +// //To draw text, QPainter need a Qrect. Instead of create an instance +// //for each text, we re-use the same instance of QRect. +// QRect text_rect; +// painter->save(); - auto pen_{painter->pen()}; - pen_.setColor(Qt::black); - pen_.setWidth(1); +// auto pen_{painter->pen()}; +// pen_.setColor(Qt::black); +// pen_.setWidth(1); - auto brush_ = painter->brush(); - brush_.setColor(Qt::white); +// auto brush_ = painter->brush(); +// brush_.setColor(Qt::white); - painter->setPen(pen_); - painter->setBrush(brush_); +// painter->setPen(pen_); +// painter->setBrush(brush_); - //Draw header - painter->drawRect(m_pattern.m_header_rect); +// //Draw header +// painter->drawRect(m_pattern.m_header_rect); - //Draw the header text - painter->save(); +// //Draw the header text +// painter->save(); - if (m_pattern.m_header_text_orientation == Qt::Horizontal) - { - text_rect.setRect(0,m_pattern.m_header_rect.y(),m_pattern.m_header_rect.width(),m_pattern.m_header_rect.height()); - } - else - { - painter->translate(m_pattern.m_header_rect.bottomLeft()); - painter->rotate(270); - text_rect.setRect(0,0,m_pattern.m_header_rect.height(),m_pattern.m_header_rect.width()); - } +// if (m_pattern.m_header_text_orientation == Qt::Horizontal) +// { +// text_rect.setRect(0,m_pattern.m_header_rect.y(),m_pattern.m_header_rect.width(),m_pattern.m_header_rect.height()); +// } +// else +// { +// painter->translate(m_pattern.m_header_rect.bottomLeft()); +// painter->rotate(270); +// text_rect.setRect(0,0,m_pattern.m_header_rect.height(),m_pattern.m_header_rect.width()); +// } - const auto text_{m_strip->installation() + " " + m_strip->location() + " " + m_strip->name()}; - painter->drawText(text_rect, text_, m_pattern.headerTextOption()); - painter->restore(); +// const auto text_{m_strip->installation() + " " + m_strip->location() + " " + m_strip->name()}; +// painter->drawText(text_rect, text_, m_pattern.headerTextOption()); +// painter->restore(); - //Move painter pos to next drawing - painter->translate(m_pattern.m_header_rect.width(),0); +// //Move painter pos to next drawing +// painter->translate(m_pattern.m_header_rect.width(),0); - int x_offset{m_pattern.m_header_rect.width()}; +// int x_offset{m_pattern.m_header_rect.width()}; - //Draw spacer - painter->drawRect(m_pattern.m_spacer_rect); - //Move painter pos to next drawing - painter->translate(m_pattern.m_spacer_rect.width(),0); - x_offset += m_pattern.m_spacer_rect.width(); +// //Draw spacer +// painter->drawRect(m_pattern.m_spacer_rect); +// //Move painter pos to next drawing +// painter->translate(m_pattern.m_spacer_rect.width(),0); +// x_offset += m_pattern.m_spacer_rect.width(); - //Draw terminals - const auto terminals_text_rect{m_pattern.m_terminals_text_rect}; - const auto terminals_text_orientation{m_pattern.m_terminals_text_orientation}; - const auto terminals_text_option{m_pattern.terminalsTextOption()}; - QRect terminal_rect; +// //Draw terminals +// const auto terminals_text_rect{m_pattern.m_terminals_text_rect}; +// const auto terminals_text_orientation{m_pattern.m_terminals_text_orientation}; +// const auto terminals_text_option{m_pattern.terminalsTextOption()}; +// QRect terminal_rect; - QHash> bridges_anchor_points; +// QHash> bridges_anchor_points; - //Loop over physical terminals - for (const auto &physical_t : m_strip->physicalTerminal()) - { - //Get the good offset according to how many level have the current physical terminal - const QVector> real_terminal{physical_t->realTerminals()}; - const auto real_t_count{real_terminal.size()}; - const auto offset_{4 - real_t_count}; +// //Loop over physical terminals +// for (const auto &physical_t : m_strip->physicalTerminal()) +// { +// //Get the good offset according to how many level have the current physical terminal +// const QVector> real_terminal{physical_t->realTerminals()}; +// const auto real_t_count{real_terminal.size()}; +// const auto offset_{4 - real_t_count}; - //Loop over real terminals - for (auto i=0 ; i= 4) { - break; - } +// //Loop over real terminals +// for (auto i=0 ; i= 4) { +// break; +// } - terminal_rect = m_pattern.m_terminal_rect[index_]; - //Draw terminal rect - painter->drawRect(terminal_rect); +// terminal_rect = m_pattern.m_terminal_rect[index_]; +// //Draw terminal rect +// painter->drawRect(terminal_rect); - //Draw text - painter->save(); - if (terminals_text_orientation[index_] == Qt::Horizontal) - { - text_rect = terminals_text_rect[index_]; - } - else - { - const auto rect_{terminals_text_rect[index_]}; - painter->translate(rect_.bottomLeft()); - painter->rotate(270); - text_rect.setRect(0, 0, rect_.height(), rect_.width()); - } +// //Draw text +// painter->save(); +// if (terminals_text_orientation[index_] == Qt::Horizontal) +// { +// text_rect = terminals_text_rect[index_]; +// } +// else +// { +// const auto rect_{terminals_text_rect[index_]}; +// painter->translate(rect_.bottomLeft()); +// painter->rotate(270); +// text_rect.setRect(0, 0, rect_.height(), rect_.width()); +// } - const auto shared_real_terminal{real_terminal[i]}; - painter->drawText(text_rect, - shared_real_terminal ? shared_real_terminal->label() : QLatin1String(), - terminals_text_option[index_]); - painter->restore(); +// const auto shared_real_terminal{real_terminal[i]}; +// painter->drawText(text_rect, +// shared_real_terminal ? shared_real_terminal->label() : QLatin1String(), +// terminals_text_option[index_]); +// painter->restore(); - //Add bridge anchor - if (shared_real_terminal->isBridged()) - { - painter->save(); - if (const auto bridge_ = shared_real_terminal->bridge()) - { - const auto anchor_center{m_pattern.m_bridge_point_d/2}; - painter->setBrush(Qt::SolidPattern); - painter->drawEllipse(QPointF{terminal_rect.width()/2, m_pattern.m_bridge_point_y_offset[index_]}, - anchor_center, - anchor_center); +// //Add bridge anchor +// if (shared_real_terminal->isBridged()) +// { +// painter->save(); +// if (const auto bridge_ = shared_real_terminal->bridge()) +// { +// const auto anchor_center{m_pattern.m_bridge_point_d/2}; +// painter->setBrush(Qt::SolidPattern); +// painter->drawEllipse(QPointF{terminal_rect.width()/2, m_pattern.m_bridge_point_y_offset[index_]}, +// anchor_center, +// anchor_center); - auto anchor_points{bridges_anchor_points.value(bridge_->uuid())}; - anchor_points.append(QPointF{x_offset + terminal_rect.width()/2, - m_pattern.m_bridge_point_y_offset[index_]}); - bridges_anchor_points.insert(bridge_->uuid(), anchor_points); - } - painter->restore(); - } +// auto anchor_points{bridges_anchor_points.value(bridge_->uuid())}; +// anchor_points.append(QPointF{x_offset + terminal_rect.width()/2, +// m_pattern.m_bridge_point_y_offset[index_]}); +// bridges_anchor_points.insert(bridge_->uuid(), anchor_points); +// } +// painter->restore(); +// } - //Move painter pos to next drawing - painter->translate(terminal_rect.width(),0); - x_offset += terminal_rect.width(); - } - } +// //Move painter pos to next drawing +// painter->translate(terminal_rect.width(),0); +// x_offset += terminal_rect.width(); +// } +// } - painter->restore(); +// painter->restore(); - //Draw the bridges - for (const auto &points_ : qAsConst(bridges_anchor_points)) - { - painter->save(); - auto pen_{painter->pen()}; - pen_.setWidth(2); - painter->setPen(pen_); - painter->drawPolyline(QPolygonF{points_}); - painter->restore(); - } - } -} +// //Draw the bridges +// for (const auto &points_ : qAsConst(bridges_anchor_points)) +// { +// painter->save(); +// auto pen_{painter->pen()}; +// pen_.setWidth(2); +// painter->setPen(pen_); +// painter->drawPolyline(QPolygonF{points_}); +// painter->restore(); +// } +// } +//} -QRectF TerminalStripDrawer::boundingRect() const -{ - return QRect{0, 0, width(), height()};; -} +//QRectF TerminalStripDrawer::boundingRect() const +//{ +// return QRect{0, 0, width(), height()};; +//} -int TerminalStripDrawer::height() const -{ - auto height_{m_pattern.m_header_rect.y() + m_pattern.m_header_rect.height()}; +//int TerminalStripDrawer::height() const +//{ +// auto height_{m_pattern.m_header_rect.y() + m_pattern.m_header_rect.height()}; - height_ = std::max(height_, m_pattern.m_spacer_rect.y() + m_pattern.m_spacer_rect.height()); +// height_ = std::max(height_, m_pattern.m_spacer_rect.y() + m_pattern.m_spacer_rect.height()); - for (const auto &rect : m_pattern.m_terminal_rect) { - height_ = std::max(height_, rect.y() + rect.height()); - } +// for (const auto &rect : m_pattern.m_terminal_rect) { +// height_ = std::max(height_, rect.y() + rect.height()); +// } - return height_; -} +// return height_; +//} -int TerminalStripDrawer::width() const -{ - int width_{m_pattern.m_header_rect.width() + m_pattern.m_spacer_rect.width()}; +//int TerminalStripDrawer::width() const +//{ +// int width_{m_pattern.m_header_rect.width() + m_pattern.m_spacer_rect.width()}; - if (m_strip) - { - //Loop over physical terminals - for (const auto &physical_t : m_strip->physicalTerminal()) - { - //Get the good offset according to how many level have the current physical terminal - const QVector> real_terminal{physical_t->realTerminals()}; - const auto real_t_count{real_terminal.size()}; - const auto offset_{4 - real_t_count}; +// if (m_strip) +// { +// //Loop over physical terminals +// for (const auto &physical_t : m_strip->physicalTerminal()) +// { +// //Get the good offset according to how many level have the current physical terminal +// const QVector> real_terminal{physical_t->realTerminals()}; +// const auto real_t_count{real_terminal.size()}; +// const auto offset_{4 - real_t_count}; - //Loop over real terminals - for (auto i=0 ; i= 4) { - break; - } +// //Loop over real terminals +// for (auto i=0 ; i= 4) { +// break; +// } - width_ += m_pattern.m_terminal_rect[index_].width(); - } - } - } +// width_ += m_pattern.m_terminal_rect[index_].width(); +// } +// } +// } - return width_; -} +// return width_; +//} TerminalStripLayoutPattern::TerminalStripLayoutPattern() { diff --git a/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.h b/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.h index 65c5db3a5..451db1d6c 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.h +++ b/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.h @@ -18,14 +18,14 @@ #ifndef TERMINALSTRIPLAYOUTPATTERN_H #define TERMINALSTRIPLAYOUTPATTERN_H -#include +//#include #include #include #include #include -class QPainter; -class TerminalStrip; +//class QPainter; +//class TerminalStrip; /** * @brief The TerminalStripLayoutPattern class @@ -110,21 +110,21 @@ class TerminalStripLayoutPattern }; }; -class TerminalStripDrawer -{ - public: - TerminalStripDrawer(QPointer strip); - void paint(QPainter *painter); +//class TerminalStripDrawer +//{ +// public: +// TerminalStripDrawer(QPointer strip); +// void paint(QPainter *painter); - QRectF boundingRect() const; +// QRectF boundingRect() const; - private: - int height() const; - int width() const; +// private: +// int height() const; +// int width() const; - private: - QPointer m_strip; - TerminalStripLayoutPattern m_pattern; -}; +// private: +// QPointer m_strip; +// TerminalStripLayoutPattern m_pattern; +//}; #endif // TERMINALSTRIPLAYOUTPATTERN_H From f41b5a4ed441f6501d091728c0084539e6cfe00b Mon Sep 17 00:00:00 2001 From: joshua Date: Fri, 2 Dec 2022 19:39:56 +0100 Subject: [PATCH 11/12] See previous commit... MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Je suis une tête de linotte --- .../GraphicsItem/terminalstripdrawer.h | 1 - .../terminalstriplayoutpattern.cpp | 209 ------------------ .../GraphicsItem/terminalstriplayoutpattern.h | 21 -- 3 files changed, 231 deletions(-) diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h index c59e5f8e4..a7f3a4c11 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h +++ b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h @@ -19,7 +19,6 @@ #define TERMINALSTRIPDRAWER_H #include - #include "terminalstriplayoutpattern.h" class QPainter; diff --git a/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp b/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp index 2df7976d5..f0b8801c9 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp +++ b/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.cpp @@ -18,215 +18,6 @@ #include "terminalstriplayoutpattern.h" #include -//#include "../physicalterminal.h" -//#include "../realterminal.h" -//#include "../terminalstrip.h" -//#include "../terminalstripbridge.h" - -//#include - -///** -// * @brief TerminalStripDrawer::TerminalStripDrawer -// * @param strip -// * @param pattern -// */ -//TerminalStripDrawer::TerminalStripDrawer(QPointer strip) : -// m_strip(strip) -//{} - -///** -// * @brief TerminalStripDrawer::paint -// * @param painter -// */ -//void TerminalStripDrawer::paint(QPainter *painter) -//{ -// if (m_strip) -// { -// //To draw text, QPainter need a Qrect. Instead of create an instance -// //for each text, we re-use the same instance of QRect. -// QRect text_rect; -// painter->save(); - -// auto pen_{painter->pen()}; -// pen_.setColor(Qt::black); -// pen_.setWidth(1); - -// auto brush_ = painter->brush(); -// brush_.setColor(Qt::white); - -// painter->setPen(pen_); -// painter->setBrush(brush_); - -// //Draw header -// painter->drawRect(m_pattern.m_header_rect); - -// //Draw the header text -// painter->save(); - -// if (m_pattern.m_header_text_orientation == Qt::Horizontal) -// { -// text_rect.setRect(0,m_pattern.m_header_rect.y(),m_pattern.m_header_rect.width(),m_pattern.m_header_rect.height()); -// } -// else -// { -// painter->translate(m_pattern.m_header_rect.bottomLeft()); -// painter->rotate(270); -// text_rect.setRect(0,0,m_pattern.m_header_rect.height(),m_pattern.m_header_rect.width()); -// } - -// const auto text_{m_strip->installation() + " " + m_strip->location() + " " + m_strip->name()}; -// painter->drawText(text_rect, text_, m_pattern.headerTextOption()); -// painter->restore(); - -// //Move painter pos to next drawing -// painter->translate(m_pattern.m_header_rect.width(),0); - -// int x_offset{m_pattern.m_header_rect.width()}; - -// //Draw spacer -// painter->drawRect(m_pattern.m_spacer_rect); -// //Move painter pos to next drawing -// painter->translate(m_pattern.m_spacer_rect.width(),0); -// x_offset += m_pattern.m_spacer_rect.width(); - - -// //Draw terminals -// const auto terminals_text_rect{m_pattern.m_terminals_text_rect}; -// const auto terminals_text_orientation{m_pattern.m_terminals_text_orientation}; -// const auto terminals_text_option{m_pattern.terminalsTextOption()}; -// QRect terminal_rect; - -// QHash> bridges_anchor_points; - -// //Loop over physical terminals -// for (const auto &physical_t : m_strip->physicalTerminal()) -// { -// //Get the good offset according to how many level have the current physical terminal -// const QVector> real_terminal{physical_t->realTerminals()}; -// const auto real_t_count{real_terminal.size()}; -// const auto offset_{4 - real_t_count}; - -// //Loop over real terminals -// for (auto i=0 ; i= 4) { -// break; -// } - -// terminal_rect = m_pattern.m_terminal_rect[index_]; -// //Draw terminal rect -// painter->drawRect(terminal_rect); - -// //Draw text -// painter->save(); -// if (terminals_text_orientation[index_] == Qt::Horizontal) -// { -// text_rect = terminals_text_rect[index_]; -// } -// else -// { -// const auto rect_{terminals_text_rect[index_]}; -// painter->translate(rect_.bottomLeft()); -// painter->rotate(270); -// text_rect.setRect(0, 0, rect_.height(), rect_.width()); -// } - -// const auto shared_real_terminal{real_terminal[i]}; -// painter->drawText(text_rect, -// shared_real_terminal ? shared_real_terminal->label() : QLatin1String(), -// terminals_text_option[index_]); -// painter->restore(); - -// //Add bridge anchor -// if (shared_real_terminal->isBridged()) -// { -// painter->save(); -// if (const auto bridge_ = shared_real_terminal->bridge()) -// { -// const auto anchor_center{m_pattern.m_bridge_point_d/2}; -// painter->setBrush(Qt::SolidPattern); -// painter->drawEllipse(QPointF{terminal_rect.width()/2, m_pattern.m_bridge_point_y_offset[index_]}, -// anchor_center, -// anchor_center); - -// auto anchor_points{bridges_anchor_points.value(bridge_->uuid())}; -// anchor_points.append(QPointF{x_offset + terminal_rect.width()/2, -// m_pattern.m_bridge_point_y_offset[index_]}); -// bridges_anchor_points.insert(bridge_->uuid(), anchor_points); -// } -// painter->restore(); -// } - -// //Move painter pos to next drawing -// painter->translate(terminal_rect.width(),0); -// x_offset += terminal_rect.width(); -// } -// } - -// painter->restore(); - -// //Draw the bridges -// for (const auto &points_ : qAsConst(bridges_anchor_points)) -// { -// painter->save(); -// auto pen_{painter->pen()}; -// pen_.setWidth(2); -// painter->setPen(pen_); -// painter->drawPolyline(QPolygonF{points_}); -// painter->restore(); -// } -// } -//} - -//QRectF TerminalStripDrawer::boundingRect() const -//{ -// return QRect{0, 0, width(), height()};; -//} - -//int TerminalStripDrawer::height() const -//{ -// auto height_{m_pattern.m_header_rect.y() + m_pattern.m_header_rect.height()}; - -// height_ = std::max(height_, m_pattern.m_spacer_rect.y() + m_pattern.m_spacer_rect.height()); - -// for (const auto &rect : m_pattern.m_terminal_rect) { -// height_ = std::max(height_, rect.y() + rect.height()); -// } - -// return height_; -//} - -//int TerminalStripDrawer::width() const -//{ -// int width_{m_pattern.m_header_rect.width() + m_pattern.m_spacer_rect.width()}; - -// if (m_strip) -// { -// //Loop over physical terminals -// for (const auto &physical_t : m_strip->physicalTerminal()) -// { -// //Get the good offset according to how many level have the current physical terminal -// const QVector> real_terminal{physical_t->realTerminals()}; -// const auto real_t_count{real_terminal.size()}; -// const auto offset_{4 - real_t_count}; - -// //Loop over real terminals -// for (auto i=0 ; i= 4) { -// break; -// } - -// width_ += m_pattern.m_terminal_rect[index_].width(); -// } -// } -// } - -// return width_; -//} - TerminalStripLayoutPattern::TerminalStripLayoutPattern() { updateHeaderTextOption(); diff --git a/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.h b/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.h index 451db1d6c..2a6fd0f3d 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.h +++ b/sources/TerminalStrip/GraphicsItem/terminalstriplayoutpattern.h @@ -18,15 +18,11 @@ #ifndef TERMINALSTRIPLAYOUTPATTERN_H #define TERMINALSTRIPLAYOUTPATTERN_H -//#include #include #include #include #include -//class QPainter; -//class TerminalStrip; - /** * @brief The TerminalStripLayoutPattern class * A class with all values used to define how a terminal strip must be drawn. @@ -110,21 +106,4 @@ class TerminalStripLayoutPattern }; }; -//class TerminalStripDrawer -//{ -// public: -// TerminalStripDrawer(QPointer strip); -// void paint(QPainter *painter); - -// QRectF boundingRect() const; - -// private: -// int height() const; -// int width() const; - -// private: -// QPointer m_strip; -// TerminalStripLayoutPattern m_pattern; -//}; - #endif // TERMINALSTRIPLAYOUTPATTERN_H From f54bea713e5198f5060b4c3b991b94d09fbf7575 Mon Sep 17 00:00:00 2001 From: joshua Date: Wed, 21 Dec 2022 19:18:49 +0100 Subject: [PATCH 12/12] 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