diff --git a/sources/symboltextplacement.cpp b/sources/symboltextplacement.cpp index 871a971bd..0823f7d1d 100644 --- a/sources/symboltextplacement.cpp +++ b/sources/symboltextplacement.cpp @@ -46,6 +46,9 @@ struct Line QGraphicsItem *item; ///< for where it stands QPointF old_pos; QVariant old_alignment; + /// For a group, where its texts lay: a new alignment lays them out + /// anew, and undoing it to AlignJustify lays out nothing + QList> old_texts; }; /// Move @a item so that the top left of its box in the folio is at @a to @@ -65,10 +68,15 @@ bool placeOne(Element *element, Qt::Alignment where, QUndoCommand *parent) QList lines; for (DynamicElementTextItem *text : element->dynamicTextItems()) if (!text->parentGroup() && text->isVisible()) - lines.append({text, text, text->pos(), text->property("alignment")}); + lines.append({text, text, text->pos(), text->property("alignment"), {}}); for (ElementTextItemGroup *group : element->textGroups()) if (group->isVisible()) - lines.append({group, group, group->pos(), group->property("alignment")}); + { + Line line {group, group, group->pos(), group->property("alignment"), {}}; + for (DynamicElementTextItem *text : group->texts()) + line.old_texts.append({text, text->pos()}); + lines.append(line); + } if (lines.isEmpty()) return false; @@ -112,6 +120,11 @@ bool placeOne(Element *element, Qt::Alignment where, QUndoCommand *parent) new QPropertyUndoCommand(line.object, "alignment", line.old_alignment, alignment, parent); if (line.item->pos() != line.old_pos) new QPropertyUndoCommand(line.object, "pos", line.old_pos, line.item->pos(), parent); + //The group's texts too: undoing its alignment to AlignJustify + //would leave them where the new alignment put them + for (const auto &text : line.old_texts) + if (text.first->pos() != text.second) + new QPropertyUndoCommand(text.first, "pos", text.second, text.first->pos(), parent); } return true; } diff --git a/tests/qttest/symbol_text_placement_probe.cpp b/tests/qttest/symbol_text_placement_probe.cpp index 5f29402b0..1b5271ebc 100644 --- a/tests/qttest/symbol_text_placement_probe.cpp +++ b/tests/qttest/symbol_text_placement_probe.cpp @@ -136,6 +136,25 @@ int main(int argc, char **argv) "a group is placed as one line of the block"); check(group->alignment() == Qt::AlignRight, "and is aligned right too"); + // A group whose texts lie freely (AlignJustify, the default of the + // "Label and comment" group): placing it lays its texts out anew, + // and one undo puts them back where they lay, not only the group. + scene->undoStack().undo(); + group->setAlignment(Qt::AlignJustify); + texts[1]->setPos(0, 0); + texts[2]->setPos(5, 12); + const QPointF group_pos = group->pos(); + scene->undoStack().push(SymbolTextPlacement::place({element}, Qt::AlignRight | Qt::AlignVCenter)); + check(texts[2]->pos() != QPointF(5, 12), "placing lays the group's texts out anew"); + scene->undoStack().undo(); + check(group->alignment() == Qt::AlignJustify && group->pos() == group_pos, + "undo puts the group's alignment and place back"); + check(texts[1]->pos() == QPointF(0, 0) && texts[2]->pos() == QPointF(5, 12), + "undo puts the group's texts back where they lay"); + scene->undoStack().redo(); + check(group->alignment() == Qt::AlignLeft && texts[2]->pos() != QPointF(5, 12), + "redo places them again"); + // A symbol with no texts: nothing to undo. Element *other = nullptr; for (Element *e : scene->elements()) if (e != element) other = e;