Files
qelectrotech-source-mirror/tests/qttest/tst_itemgroups.cpp
T
ispyisail a8f940505d Rotate a selected group as one piece
Discussion #1070 proposed that rotate, like move, copy and delete, works on
the whole group once one of its items is clicked. Rotate (Space) turned
each member on its own spot instead, so rotating a group pulled it apart:
two grouped texts side by side ended up each turned in place, no longer
side by side.

When the selection is exactly one whole group -- wires aside, which follow
their symbols -- Rotate now turns it as one piece around its centre, as
"Pivoter le groupe" (Shift+Space) already does
(ItemGroups::soleWholeGroup()). Any other selection, including a single
member picked out of its group, rotates as before.

In the GUI, on two grouped texts selected by one click: Space on master
leaves both where they were, turned; here it gives exactly what
Shift+Space gives on both (both texts swung around the group's centre).
tst_itemgroups: 4 new checks; without the whole-group condition, a
picked member counts as a group and fails. ctest 24/24.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 22:39:03 +13:00

171 lines
3.9 KiB
C++

#include <QtTest>
#include <QDomDocument>
#include <QGraphicsRectItem>
#include <QGraphicsScene>
#include "itemgroups.h"
class tst_itemgroups : public QObject
{
Q_OBJECT
QGraphicsScene *scene = nullptr;
QGraphicsRectItem *a = nullptr, *b = nullptr, *c = nullptr, *d = nullptr, *e = nullptr;
QUuid g1, g2;
QGraphicsRectItem *add()
{
auto item = scene->addRect(0, 0, 10, 10);
item->setFlag(QGraphicsItem::ItemIsSelectable);
return item;
}
QList<QGraphicsItem *> selection() const { return scene->selectedItems(); }
// Select exactly @a items, as Qt leaves the scene after a click.
void select(const QList<QGraphicsItem *> &items)
{
scene->clearSelection();
for (auto item : items) {
item->setSelected(true);
}
}
bool selected(std::initializer_list<QGraphicsItem *> expected) const
{
QList<QGraphicsItem *> got = selection();
if (got.size() != int(expected.size())) {
return false;
}
for (auto item : expected) {
if (!got.contains(item)) {
return false;
}
}
return true;
}
private slots:
// a, b in g1; c alone; d, e in g2
void init()
{
scene = new QGraphicsScene;
a = add(); b = add(); c = add(); d = add(); e = add();
g1 = QUuid::createUuid();
g2 = QUuid::createUuid();
ItemGroups::setGroup(a, g1);
ItemGroups::setGroup(b, g1);
ItemGroups::setGroup(d, g2);
ItemGroups::setGroup(e, g2);
}
void cleanup()
{
delete scene;
scene = nullptr;
}
void clickingAMemberSelectsTheGroup()
{
select({a});
QVERIFY(ItemGroups::completeSelection(scene, {}, false));
QVERIFY(selected({a, b}));
}
// Releasing a click on one member of the selected group leaves only it
// selected in Qt; the group must stay whole.
void reclickingAMemberKeepsTheGroup()
{
select({b});
ItemGroups::completeSelection(scene, {a, b}, false);
QVERIFY(selected({a, b}));
}
void ctrlClickingAMemberOffDeselectsTheGroup()
{
select({b});
ItemGroups::completeSelection(scene, {a, b}, true);
QVERIFY(selected({}));
}
void ctrlClickingAMemberOnAddsTheGroup()
{
select({c, a});
ItemGroups::completeSelection(scene, {c}, true);
QVERIFY(selected({a, b, c}));
}
void otherGroupsAreUntouched()
{
select({b, d, e});
ItemGroups::completeSelection(scene, {a, b, d, e}, true);
QVERIFY(selected({d, e}));
}
void ungroupedItemsAreUntouched()
{
select({c});
QVERIFY(!ItemGroups::completeSelection(scene, {}, false));
QVERIFY(selected({c}));
}
// A member taken off the scene (deleted, kept by the undo stack) must
// not count as "deselected".
void itemsLeavingTheSceneAreIgnored()
{
select({a, b});
scene->removeItem(b);
ItemGroups::completeSelection(scene, {a, b}, true);
QVERIFY(selected({a}));
delete b;
b = nullptr;
}
void xmlRoundTrip()
{
QDomDocument doc;
QDomElement grouped = doc.createElement(QStringLiteral("element"));
ItemGroups::write(grouped, a);
QCOMPARE(ItemGroups::read(grouped), g1);
QDomElement alone = doc.createElement(QStringLiteral("element"));
ItemGroups::write(alone, c);
QVERIFY(!alone.hasAttribute(QStringLiteral("group")));
QVERIFY(ItemGroups::read(alone).isNull());
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)
#include "tst_itemgroups.moc"