Merge pull request #1111 from ispyisail/feat/1070-rotate-whole-group

Rotate a selected group as one piece
This commit is contained in:
Laurent Trinques
2026-09-28 14:55:04 +02:00
committed by GitHub
4 changed files with 73 additions and 1 deletions
+31
View File
@@ -163,3 +163,34 @@ bool ItemGroups::completeSelection(QGraphicsScene *scene,
}
return changed;
}
/**
@return the group @a selected is exactly, whole -- every item in it
belongs to that group and every member of the group is in it -- or a null
uuid. Rotating such a selection turns the group as one piece rather than
each member in place (discussion #1070). A member picked out on its own
is not a whole group, and turns in place.
@param selected : the selected items that can be members (the caller
leaves out wires, which follow their symbols)
*/
QUuid ItemGroups::soleWholeGroup(const QList<QGraphicsItem *> &selected)
{
if (selected.isEmpty() || !selected.first()->scene()) {
return QUuid();
}
const QUuid group = groupOf(selected.first());
if (group.isNull()) {
return QUuid();
}
for (QGraphicsItem *item : selected) {
if (groupOf(item) != group) {
return QUuid();
}
}
for (QGraphicsItem *item : selected.first()->scene()->items()) {
if (groupOf(item) == group && !item->isSelected()) {
return QUuid();
}
}
return group;
}
+2
View File
@@ -58,6 +58,8 @@ namespace ItemGroups
bool completeSelection(QGraphicsScene *scene,
const QList<QGraphicsItem *> &previous,
bool toggling);
QUuid soleWholeGroup(const QList<QGraphicsItem *> &selected);
}
#endif // ITEMGROUPS_H
+12 -1
View File
@@ -25,6 +25,7 @@
#include "ElementsCollection/elementpickerpopup.h"
#include "shortcutbarsettings.h"
#include "qetgraphicsitem/conductor.h"
#include "itemgroups.h"
#include "commandsearchpopup.h"
#include "QWidgetAnimation/qwidgetanimation.h"
#include "autoNum/ui/autonumberingdockwidget.h"
@@ -2078,7 +2079,17 @@ void QETDiagramEditor::selectionGroupTriggered(QAction *action)
}
else if (value == "rotate_selection")
{
RotateSelectionCommand *c = new RotateSelectionCommand(diagram);
//A selection that is exactly one whole group turns as one piece,
//as "Pivoter le groupe" does, rather than each member in place
//(discussion #1070). Wires follow their symbols either way.
QList<QGraphicsItem *> members;
for (QGraphicsItem *item : diagram->selectedItems()) {
if (item->type() != Conductor::Type) {
members << item;
}
}
const bool whole_group = !ItemGroups::soleWholeGroup(members).isNull();
RotateSelectionCommand *c = new RotateSelectionCommand(diagram, 90, nullptr, whole_group);
if(c->isValid())
diagram->undoStack().push(c);
}
+28
View File
@@ -178,6 +178,34 @@ private slots:
ItemGroups::setGroup(a, QUuid());
QVERIFY(ItemGroups::groupOf(a).isNull());
}
// Rotate turns a selection that is exactly one whole group as one piece.
void aWholeGroupAloneIsASoleWholeGroup()
{
select({a, b});
QCOMPARE(ItemGroups::soleWholeGroup(selection()), g1);
}
void aPickedMemberIsNotAWholeGroup()
{
select({a});
QVERIFY(ItemGroups::soleWholeGroup(selection()).isNull());
}
void aGroupWithOtherItemsIsNotASoleGroup()
{
select({a, b, c});
QVERIFY(ItemGroups::soleWholeGroup(selection()).isNull());
select({a, b, d, e});
QVERIFY(ItemGroups::soleWholeGroup(selection()).isNull());
}
void ungroupedItemsAreNotAGroup()
{
select({c});
QVERIFY(ItemGroups::soleWholeGroup(selection()).isNull());
QVERIFY(ItemGroups::soleWholeGroup({}).isNull());
}
};
QTEST_MAIN(tst_itemgroups)