mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-08-13 10:04:13 +02:00
autoBreakConductors: share conductors_handled/used_terminals across batch
When multiple elements are pasted or moved in one batch, each call to autoBreakConductors() now receives the shared state from the previous call. This prevents two elements in the same batch from independently claiming the same conductor, which would result in a double-delete on redo(). Requested by ispyisail in PR review.
This commit is contained in:
@@ -71,16 +71,15 @@ qreal distanceToSegment(const QPointF &point, const QLineF &segment)
|
|||||||
QSet<Terminal *> autoBreakConductors(
|
QSet<Terminal *> autoBreakConductors(
|
||||||
Diagram *diagram,
|
Diagram *diagram,
|
||||||
Element *element,
|
Element *element,
|
||||||
QUndoCommand *parent)
|
QUndoCommand *parent,
|
||||||
|
QList<Conductor *> &conductors_handled,
|
||||||
|
QSet<Terminal *> &used_terminals)
|
||||||
{
|
{
|
||||||
QSet<Terminal *> broken_endpoints;
|
QSet<Terminal *> broken_endpoints;
|
||||||
|
|
||||||
if (!diagram->project()->autoBreakConductor())
|
if (!diagram->project()->autoBreakConductor())
|
||||||
return broken_endpoints;
|
return broken_endpoints;
|
||||||
|
|
||||||
QList<Conductor *> conductors_handled;
|
|
||||||
QSet<Terminal *> used_terminals;
|
|
||||||
|
|
||||||
foreach (Terminal *t, element->terminals())
|
foreach (Terminal *t, element->terminals())
|
||||||
{
|
{
|
||||||
if (used_terminals.contains(t))
|
if (used_terminals.contains(t))
|
||||||
|
|||||||
@@ -19,10 +19,12 @@
|
|||||||
#define AUTOBREAKCONDUCTOR_H
|
#define AUTOBREAKCONDUCTOR_H
|
||||||
|
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
class Diagram;
|
class Diagram;
|
||||||
class Element;
|
class Element;
|
||||||
class Terminal;
|
class Terminal;
|
||||||
|
class Conductor;
|
||||||
class QUndoCommand;
|
class QUndoCommand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,15 +36,22 @@ class QUndoCommand;
|
|||||||
conductors are left untouched.
|
conductors are left untouched.
|
||||||
@param diagram the diagram containing the conductors
|
@param diagram the diagram containing the conductors
|
||||||
@param element the element whose terminals trigger breaks
|
@param element the element whose terminals trigger breaks
|
||||||
@param parent undo command under which break/reconnect sub-commands
|
@param parent undo command under which break/reconnect
|
||||||
are created (may be nullptr, in which case no undo is
|
sub-commands are created
|
||||||
recorded)
|
@param conductors_handled shared list of conductors already claimed by
|
||||||
|
a previous call in the same batch (prevents
|
||||||
|
double-processing when multiple elements are
|
||||||
|
broken in one pass)
|
||||||
|
@param used_terminals shared set of terminals already used as
|
||||||
|
connect_to or other_terminal in the same batch
|
||||||
@return set of terminals that were connected to a broken conductor's
|
@return set of terminals that were connected to a broken conductor's
|
||||||
far-end (useful for preventing duplicate auto-connect)
|
far-end (useful for preventing duplicate auto-connect)
|
||||||
*/
|
*/
|
||||||
QSet<Terminal *> autoBreakConductors(
|
QSet<Terminal *> autoBreakConductors(
|
||||||
Diagram *diagram,
|
Diagram *diagram,
|
||||||
Element *element,
|
Element *element,
|
||||||
QUndoCommand *parent);
|
QUndoCommand *parent,
|
||||||
|
QList<Conductor *> &conductors_handled,
|
||||||
|
QSet<Terminal *> &used_terminals);
|
||||||
|
|
||||||
#endif // AUTOBREAKCONDUCTOR_H
|
#endif // AUTOBREAKCONDUCTOR_H
|
||||||
|
|||||||
@@ -115,8 +115,11 @@ void PasteDiagramCommand::redo()
|
|||||||
if (diagram->project()->autoBreakConductor())
|
if (diagram->project()->autoBreakConductor())
|
||||||
{
|
{
|
||||||
m_break_cmd = new QUndoCommand();
|
m_break_cmd = new QUndoCommand();
|
||||||
|
QList<Conductor *> conductors_handled;
|
||||||
|
QSet<Terminal *> used_terminals;
|
||||||
for (Element *e : content.m_elements) {
|
for (Element *e : content.m_elements) {
|
||||||
autoBreakConductors(diagram, e, m_break_cmd);
|
autoBreakConductors(diagram, e, m_break_cmd,
|
||||||
|
conductors_handled, used_terminals);
|
||||||
}
|
}
|
||||||
if (m_break_cmd->childCount() == 0) {
|
if (m_break_cmd->childCount() == 0) {
|
||||||
delete m_break_cmd;
|
delete m_break_cmd;
|
||||||
|
|||||||
@@ -265,7 +265,10 @@ void DiagramEventAddElement::addElement()
|
|||||||
//Auto break conductor: if a terminal of the new element lies on an existing
|
//Auto break conductor: if a terminal of the new element lies on an existing
|
||||||
//conductor, break the conductor and reconnect through the new element's terminal.
|
//conductor, break the conductor and reconnect through the new element's terminal.
|
||||||
//Track the endpoints of broken conductors so auto-connect doesn't create duplicates.
|
//Track the endpoints of broken conductors so auto-connect doesn't create duplicates.
|
||||||
QSet<Terminal *> broken_endpoints = autoBreakConductors(m_diagram, element, undo_object);
|
QList<Conductor *> conductors_handled;
|
||||||
|
QSet<Terminal *> used_terminals;
|
||||||
|
QSet<Terminal *> broken_endpoints = autoBreakConductors(m_diagram, element, undo_object,
|
||||||
|
conductors_handled, used_terminals);
|
||||||
|
|
||||||
//Auto-connect: collect all aligned pairs first, then filter and process.
|
//Auto-connect: collect all aligned pairs first, then filter and process.
|
||||||
QList<QPair<Terminal *, Terminal *>> aligned_pairs;
|
QList<QPair<Terminal *, Terminal *>> aligned_pairs;
|
||||||
|
|||||||
@@ -184,8 +184,11 @@ void ElementsMover::endMovement()
|
|||||||
//the element. The element is already at its final position on screen.
|
//the element. The element is already at its final position on screen.
|
||||||
if (m_diagram->project()->autoBreakConductor())
|
if (m_diagram->project()->autoBreakConductor())
|
||||||
{
|
{
|
||||||
|
QList<Conductor *> conductors_handled;
|
||||||
|
QSet<Terminal *> used_terminals;
|
||||||
for (Element *e : m_moved_content.m_elements) {
|
for (Element *e : m_moved_content.m_elements) {
|
||||||
autoBreakConductors(m_diagram, e, undo_object);
|
autoBreakConductors(m_diagram, e, undo_object,
|
||||||
|
conductors_handled, used_terminals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user