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(
|
||||
Diagram *diagram,
|
||||
Element *element,
|
||||
QUndoCommand *parent)
|
||||
QUndoCommand *parent,
|
||||
QList<Conductor *> &conductors_handled,
|
||||
QSet<Terminal *> &used_terminals)
|
||||
{
|
||||
QSet<Terminal *> broken_endpoints;
|
||||
|
||||
if (!diagram->project()->autoBreakConductor())
|
||||
return broken_endpoints;
|
||||
|
||||
QList<Conductor *> conductors_handled;
|
||||
QSet<Terminal *> used_terminals;
|
||||
|
||||
foreach (Terminal *t, element->terminals())
|
||||
{
|
||||
if (used_terminals.contains(t))
|
||||
|
||||
@@ -19,10 +19,12 @@
|
||||
#define AUTOBREAKCONDUCTOR_H
|
||||
|
||||
#include <QSet>
|
||||
#include <QList>
|
||||
|
||||
class Diagram;
|
||||
class Element;
|
||||
class Terminal;
|
||||
class Conductor;
|
||||
class QUndoCommand;
|
||||
|
||||
/**
|
||||
@@ -34,15 +36,22 @@ class QUndoCommand;
|
||||
conductors are left untouched.
|
||||
@param diagram the diagram containing the conductors
|
||||
@param element the element whose terminals trigger breaks
|
||||
@param parent undo command under which break/reconnect sub-commands
|
||||
are created (may be nullptr, in which case no undo is
|
||||
recorded)
|
||||
@param parent undo command under which break/reconnect
|
||||
sub-commands are created
|
||||
@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
|
||||
far-end (useful for preventing duplicate auto-connect)
|
||||
*/
|
||||
QSet<Terminal *> autoBreakConductors(
|
||||
Diagram *diagram,
|
||||
Element *element,
|
||||
QUndoCommand *parent);
|
||||
QUndoCommand *parent,
|
||||
QList<Conductor *> &conductors_handled,
|
||||
QSet<Terminal *> &used_terminals);
|
||||
|
||||
#endif // AUTOBREAKCONDUCTOR_H
|
||||
|
||||
@@ -115,8 +115,11 @@ void PasteDiagramCommand::redo()
|
||||
if (diagram->project()->autoBreakConductor())
|
||||
{
|
||||
m_break_cmd = new QUndoCommand();
|
||||
QList<Conductor *> conductors_handled;
|
||||
QSet<Terminal *> used_terminals;
|
||||
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) {
|
||||
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
|
||||
//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.
|
||||
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.
|
||||
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.
|
||||
if (m_diagram->project()->autoBreakConductor())
|
||||
{
|
||||
QList<Conductor *> conductors_handled;
|
||||
QSet<Terminal *> used_terminals;
|
||||
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