Never derive a uuid the file already carries

A symbol keeps its derived uuid once saved, even when it is moved. A
symbol saved without a uuid that later turns up on the spot it left -- a
hand edit, an older version, another tool writing the file -- derived the
same uuid, and the project had two symbols with one identity.

readDiagramsXml() now collects every symbol and wire uuid the file
carries, on any folio, before a folio loads; derivedItemUuid() moves to
the next counter value while a candidate is among them. The result still
depends on the file alone. Renamed from derivedUuid(), which QETProject
already has for the project's own uuid.

tst_derivedsymboluuid: newcomerOnAMovedSymbolsSpotGetsAnotherUuid fails
with the check switched off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-09-28 20:46:01 +13:00
parent 0721b42e21
commit e12410e439
4 changed files with 58 additions and 7 deletions
+22
View File
@@ -156,6 +156,28 @@ private slots:
QCOMPARE(symbolUuids(resave(doc)), symbolUuids(doc));
}
// A symbol keeps its derived uuid once saved, even when moved. A symbol
// saved without a uuid that later turns up on the spot it left (a hand
// edit, an older version, another tool) would derive the same uuid: it
// must get another one instead.
void newcomerOnAMovedSymbolsSpotGetsAnotherUuid()
{
QDomDocument doc = resave(fixture());
QDomElement moved = symbols(diagrams(doc).first()).first();
QVERIFY(!QUuid(moved.attribute(QStringLiteral("uuid"))).isNull());
QDomElement newcomer = moved.cloneNode(true).toElement();
newcomer.removeAttribute(QStringLiteral("uuid"));
const QDomNodeList terminals = newcomer.elementsByTagName(QStringLiteral("terminal"));
for (int i = 0; i < terminals.size(); ++i)
terminals.at(i).toElement().setAttribute(QStringLiteral("id"), 90000 + i);
moved.setAttribute(QStringLiteral("x"), moved.attribute(QStringLiteral("x")).toInt() + 500);
moved.parentNode().appendChild(newcomer);
const QMultiHash<QString, QString> after = symbolUuids(resave(doc));
QCOMPARE(after.size(), 10);
QCOMPARE(QSet<QString>(after.begin(), after.end()).size(), 10);
}
void stackedIdenticalSymbolsDiffer()
{
QDomDocument doc = fixture();