Add manual conductor routing to the scripting API

Conductor::moveSegment(index, dx, dy) is the same primitive
handlerMouseMoveEvent()/handlerMouseReleaseEvent() apply on a drag --
move both axes on the target segment (each of ConductorSegment's
moveX()/moveY() silently no-ops on the wrong axis or a static,
terminal-anchored segment), recompute the path, and push one
ChangeConductorCommand undo step via the existing saveProfile().

Caught while writing the first test for it: moveSegment() never set
modified_path, so Conductor::toXml() skipped writing <segment> children
and a manually rerouted conductor silently reverted to auto-routing on
the very next save -- the change took effect in the running scene but
never reached disk. Fixed by setting the flag, the same as every other
path-modifying call site already does.

qet.conductorSegments() lists a conductor's segments (endpoints in
scene coordinates, orientation, static/movable) so a script can find
the index it wants; qet.moveConductorSegment() applies the move and
refuses a static segment or an out-of-range index.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-09-22 14:48:17 +12:00
parent 6380e2a46b
commit ea1f65107e
4 changed files with 116 additions and 0 deletions
+28
View File
@@ -1310,6 +1310,34 @@ const QList<ConductorSegment *> Conductor::segmentsList() const
return(segments_vector);
}
/**
@brief Conductor::moveSegment
Move one segment of this conductor by (dx, dy), the same primitive
handlerMouseMoveEvent()/handlerMouseReleaseEvent() apply on a manual
drag -- moveX()/moveY() each silently no-op on the wrong axis or a
static (terminal-anchored) segment, so both are always called and
whichever applies takes effect. Unlike a drag this commits the whole
move as a single undo step.
@param index a segmentsList() index
@param dx @param dy the movement, in the diagram's own coordinates
@return false if index is out of range
*/
bool Conductor::moveSegment(int index, qreal dx, qreal dy)
{
const QList<ConductorSegment *> segs = segmentsList();
if (index < 0 || index >= segs.count()) return false;
before_mov_text_pos_ = m_text_item->pos();
ConductorSegment *seg = segs.at(index);
seg->moveX(dx);
seg->moveY(dy);
modified_path = true;
segmentsToPath();
calculateTextItemPosition();
saveProfile();
return true;
}
/**
@brief Conductor::length
@return the length of this conductor