Take the modal dialog out of RotateTextsCommand's constructor

RotateTextsCommand called QDialog::exec() from inside its constructor, so
the command could not be built without a human answering a dialog. That
made it untestable headlessly, undrivable from any script or test harness,
and it is why bugtracker #312 (PR #707) shipped with its save/reload
round-trip unverified -- the symptom could not be reproduced without a GUI.

The command now takes the angle as a parameter and does no asking. Two
statics carry the interactive half:

  hasSelectedTexts(diagram)  -- is there anything to rotate
  askRotation(rotation)      -- open the dialog, false if cancelled

The single call site in QETDiagramEditor asks first, then builds the
command, so the user-visible behaviour is unchanged: same dialog, same
title, same no-dialog-on-empty-selection. Keeping askRotation() in this
class also keeps the QObject tr() context, so existing translations of
"Orienter les textes sélectionnés" are not invalidated.

Also guards undo()/redo() against a null m_anim_group. When nothing is
selected the constructor calls setObsolete(true) without ever creating the
animation group, and QUndoStack::push() calls redo() before discarding an
obsolete command -- a latent null dereference on that path.

Verified headlessly, which was the point: driving the command through a
scratch --test-ops op on examples/741.qet (67 conductors), rotation
attributes written on save go 0 -> 67 with the #707 fix present and stay
at 0 with it reverted, while the reverted build instead writes userx on
all 67. That is bugtracker #312 reproduced and fixed under test for the
first time.
This commit is contained in:
ispyisail
2026-08-16 10:08:16 +12:00
parent ddfa234943
commit 8ab4e24b61
3 changed files with 85 additions and 17 deletions
+12 -1
View File
@@ -1856,7 +1856,18 @@ void QETDiagramEditor::selectionGroupTriggered(QAction *action)
diagram->undoStack().push(c);
}
else if (value == "rotate_selected_text")
diagram->undoStack().push(new RotateTextsCommand(diagram));
{
//Ask for the angle first, then build the command: the command
//itself no longer opens a dialog. Guarding on the selection keeps
//the previous behaviour of showing no dialog when there is
//nothing to rotate.
if (RotateTextsCommand::hasSelectedTexts(diagram))
{
qreal rotation = 0;
if (RotateTextsCommand::askRotation(rotation))
diagram->undoStack().push(new RotateTextsCommand(diagram, rotation));
}
}
else if (value == "find_selected_element" && currentElement())
findElementInPanel(currentElement()->location());
else if (value == "edit_selected_element")