From ba0a85c166af9b1392d72b01ae4d0b63a1bb9cd4 Mon Sep 17 00:00:00 2001 From: blacksun Date: Wed, 9 Jan 2019 18:08:49 +0000 Subject: [PATCH] When remove an element with several conductors connected to the same terminal, the electrical potential is partially or totally destroyed. This commit fix it : When element is removed one or several conductors are created (if needed) to conserve the electrical potential. git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5703 bfdf4180-ca20-0410-9c96-a3a8aa849046 --- .../deleteqgraphicsitemcommand.cpp | 126 +++++++++++++++++- .../undocommand/deleteqgraphicsitemcommand.h | 6 + 2 files changed, 131 insertions(+), 1 deletion(-) diff --git a/sources/undocommand/deleteqgraphicsitemcommand.cpp b/sources/undocommand/deleteqgraphicsitemcommand.cpp index 2fdac7cca..ed0835b3e 100644 --- a/sources/undocommand/deleteqgraphicsitemcommand.cpp +++ b/sources/undocommand/deleteqgraphicsitemcommand.cpp @@ -23,6 +23,8 @@ #include "conductortextitem.h" #include "elementtextitemgroup.h" #include "addelementtextcommand.h" +#include "terminal.h" +#include "diagramcommands.h" /** * @brief DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand @@ -66,9 +68,11 @@ DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand(Diagram *diagram, const D //The deletion of the groups is not managed by this undo, but by a RemoveTextsGroupCommand for(ElementTextItemGroup *group : m_removed_contents.m_texts_groups) { - new RemoveTextsGroupCommand(group->parentElement(), group, this);} + new RemoveTextsGroupCommand(group->parentElement(), group, this); + } m_removed_contents.m_texts_groups.clear(); + setPotentialsOfRemovedElements(); setText(QString(QObject::tr("supprimer %1", "undo caption - %1 is a sentence listing the removed content")).arg(m_removed_contents.sentence(DiagramContent::All))); m_diagram->qgiManager().manage(m_removed_contents.items(DiagramContent::All)); @@ -78,6 +82,126 @@ DeleteQGraphicsItemCommand::~DeleteQGraphicsItemCommand() { m_diagram->qgiManager().release(m_removed_contents.items(DiagramContent::All)); } +/** + * @brief DeleteQGraphicsItemCommand::setPotentialsOfRemovedElements + * This function creates new conductors (if needed) for conserve the electrical potentials + * present at the terminals of each removed elements. + */ +void DeleteQGraphicsItemCommand::setPotentialsOfRemovedElements() +{ + for (Element *elmt : m_removed_contents.m_elements) + { + //a list of terminals who have at least two conductors docked in. + QList terminals_list; + for (Terminal *t : elmt->terminals()) { + if (t->conductors().size() >= 2) { + terminals_list.append(t); + } + } + if (terminals_list.isEmpty()) { + continue; + } + + for (Terminal *t : terminals_list) + { + //All new created conductors will be docked to hub_terminal + Terminal *hub_terminal = nullptr; + QList terminals_to_connect_list; + + for (Conductor *c : t->conductors()) + { + Terminal *other_terminal = c->terminal1 == t ? c->terminal2 : c->terminal1; + + if (m_removed_contents.items(DiagramContent::Elements).contains(other_terminal->parentElement())) + { + other_terminal = terminalInSamePotential(other_terminal, c); + if (other_terminal == nullptr) { + continue; + } + } + + terminals_to_connect_list.append(other_terminal); + if (hub_terminal == nullptr) { + hub_terminal = other_terminal; + } + //hub_terminal must be the terminal the more at top left of the diagram. + else if (other_terminal->scenePos().x() < hub_terminal->scenePos().x()) { + hub_terminal = other_terminal; + } + else if (other_terminal->scenePos().x() == hub_terminal->scenePos().x()) { + if (other_terminal->scenePos().y() < hub_terminal->scenePos().y()) { + hub_terminal = other_terminal; + } + } + } + + terminals_to_connect_list.removeAll(hub_terminal); + if (hub_terminal == nullptr || terminals_to_connect_list.isEmpty()) { + continue; + } + + ConductorProperties properties = hub_terminal->conductors().first()->properties(); + for (Terminal *t : terminals_to_connect_list) + { + //If a conductor was already created between these two terminals + //in this undo command, from another removed element, we do nothing + bool exist_ = false; + for (QPair pair : m_connected_terminals) + { + if (pair.first == hub_terminal && pair.second == t) { + exist_ = true; + continue; + } else if (pair.first == t && pair.second == hub_terminal) { + exist_ = true; + continue; + } + } + + if (exist_ == false) + { + m_connected_terminals.append(qMakePair(hub_terminal, t)); + Conductor *new_cond = new Conductor(hub_terminal, t); + new_cond->setProperties(properties); + new AddItemCommand(new_cond, t->diagram(), QPointF(), this); + } + } + } + } +} + +/** + * @brief DeleteQGraphicsItemCommand::terminalInSamePotential + * Return a terminal at the same potential of @terminal, by traveling through the conductors connected to @terminal + * only if the owner element of the terminal is not delete by this undo command. + * Return nullptr if a terminal can't be found. + * @param terminal - terminal from search + * @param conductor_to_exclude - a conductor to exlcude from search. + * @return + */ +Terminal *DeleteQGraphicsItemCommand::terminalInSamePotential(Terminal *terminal, Conductor *conductor_to_exclude) +{ + QList conductor_list = terminal->conductors(); + conductor_list.removeAll(conductor_to_exclude); + for(Conductor *c : conductor_list) + { + Terminal *other_terminal = c->terminal1 == terminal ? c->terminal2 : c->terminal1; + if(!m_removed_contents.items(DiagramContent::Elements).contains(other_terminal->parentElement())) { + return other_terminal; + } + } + //No one of direct conductor of terminal are docked to an element which is not removed + for(Conductor *c : conductor_list) + { + Terminal *other_terminal = c->terminal1 == terminal ? c->terminal2 : c->terminal1; + Terminal *terminal_to_return = terminalInSamePotential(other_terminal, c); + if (terminal_to_return != nullptr) { + return terminal_to_return; + } + } + + return nullptr; +} + /** * @brief DeleteQGraphicsItemCommand::undo * Undo this command diff --git a/sources/undocommand/deleteqgraphicsitemcommand.h b/sources/undocommand/deleteqgraphicsitemcommand.h index 47f0a9d0e..8e88bb437 100644 --- a/sources/undocommand/deleteqgraphicsitemcommand.h +++ b/sources/undocommand/deleteqgraphicsitemcommand.h @@ -23,14 +23,19 @@ class Diagram; class ElementTextItemGroup; +class Terminal; class DeleteQGraphicsItemCommand : public QUndoCommand { public: DeleteQGraphicsItemCommand(Diagram *diagram, const DiagramContent &content, QUndoCommand * parent = nullptr); ~DeleteQGraphicsItemCommand() override; + private: DeleteQGraphicsItemCommand(const DeleteQGraphicsItemCommand &); + + void setPotentialsOfRemovedElements(); + Terminal *terminalInSamePotential(Terminal *terminal, Conductor *conductor_to_exclude); public: void undo() override; @@ -43,6 +48,7 @@ class DeleteQGraphicsItemCommand : public QUndoCommand QHash > m_link_hash; /// keep linked element for each removed element linked to other element. QHash m_elmt_text_hash; /// Keep the parent element of each deleted dynamic element text item QHash m_grp_texts_hash; ///Keep the parent group of each deleted element text item + QList > m_connected_terminals; }; #endif // DELETEQGRAPHICSITEMCOMMAND_H