[qet] qet/qet: [5703] When remove an element with several conductors connected to the same terminal , the electrical potential is partially or totally destroyed.

[ Thread Index | Date Index | More lists.tuxfamily.org/qet Archives ]


Revision: 5703
Author:   blacksun
Date:     2019-01-09 19:08:49 +0100 (Wed, 09 Jan 2019)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/sources/undocommand/deleteqgraphicsitemcommand.cpp
    trunk/sources/undocommand/deleteqgraphicsitemcommand.h

Modified: trunk/sources/undocommand/deleteqgraphicsitemcommand.cpp
===================================================================
--- trunk/sources/undocommand/deleteqgraphicsitemcommand.cpp	2019-01-09 05:07:08 UTC (rev 5702)
+++ trunk/sources/undocommand/deleteqgraphicsitemcommand.cpp	2019-01-09 18:08:49 UTC (rev 5703)
@@ -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 @@
 	
 		//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));
@@ -79,6 +83,126 @@
 }
 
 /**
+ * @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<Terminal *> 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<Terminal *> 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<Terminal *, Terminal *> 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<Terminal *, Terminal *>(hub_terminal, t));
+					Conductor *new_cond = new Conductor(hub_terminal, t);
+					new_cond->setProperties(properties);
+					new AddItemCommand<Conductor*>(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 *> 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
  */

Modified: trunk/sources/undocommand/deleteqgraphicsitemcommand.h
===================================================================
--- trunk/sources/undocommand/deleteqgraphicsitemcommand.h	2019-01-09 05:07:08 UTC (rev 5702)
+++ trunk/sources/undocommand/deleteqgraphicsitemcommand.h	2019-01-09 18:08:49 UTC (rev 5703)
@@ -23,6 +23,7 @@
 
 class Diagram;
 class ElementTextItemGroup;
+class Terminal;
 
 class DeleteQGraphicsItemCommand : public QUndoCommand
 {
@@ -29,8 +30,12 @@
 	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 @@
 		QHash <Element *, QList<Element *> > m_link_hash; /// keep linked element for each removed element linked to other element.
 		QHash <DynamicElementTextItem *, Element *> m_elmt_text_hash; /// Keep the parent element of each deleted dynamic element text item
 		QHash <DynamicElementTextItem *, ElementTextItemGroup *> m_grp_texts_hash; ///Keep the parent group of each deleted element text item
+		QList <QPair<Terminal *, Terminal *>> m_connected_terminals;
 };
 
 #endif // DELETEQGRAPHICSITEMCOMMAND_H


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/