Regenerate conductor uuids when a folio is duplicated

ElementsPanelWidget::duplicateDiagram() round-trips the folio through XML
and then gives the copied *elements* fresh uuids, because element.uuid is
the primary key of the project database and a duplicate silently fails to
insert. Conductors now have the same problem and needed the same loop:
conductor.uuid is likewise a primary key, its insert is a plain INSERT
rather than INSERT OR IGNORE, and a failure only reaches qDebug(). Without
this, every wire on a duplicated folio is missing from the wiring list and
from the per-element wire count, with nothing shown to the user.

Verified against the real schema: inserting the same conductor uuid for a
second folio fails with "UNIQUE constraint failed: conductor.uuid", leaving
one row where two were expected.

Also harden the uuid read in Conductor::fromXml(). The default argument of
QDomElement::attribute() is evaluated whether or not the attribute exists,
so a uuid was minted for every conductor on every load and thrown away; and
the default only applies when the attribute is *absent*, so a present but
empty or malformed uuid="" parsed to a null QUuid rather than a fresh one --
and null uuids collide with each other exactly as duplicates do.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-08-21 19:07:40 +12:00
parent a3511e8694
commit 0fdcd1e1e8
2 changed files with 15 additions and 1 deletions
+8
View File
@@ -17,6 +17,7 @@
*/
#include "elementspanelwidget.h"
#include "diagram.h"
#include "qetgraphicsitem/conductor.h"
#include "editor/ui/qetelementeditor.h"
#include "elementscategoryeditor.h"
#include "qetapp.h"
@@ -652,6 +653,13 @@ void ElementsPanelWidget::duplicateDiagram()
elmt->newUuid();
new_diagram->restoreText(elmt);
}
else if (Conductor *cond = dynamic_cast<Conductor *>(item)) {
// Same reasoning for conductors: conductor.uuid is the PRIMARY
// KEY of the conductor table, and its insert is a plain INSERT,
// so a duplicated uuid fails and the wire silently disappears
// from the wiring list and the per-element wire count.
cond->newUuid();
}
}
}
+7 -1
View File
@@ -1010,7 +1010,13 @@ bool Conductor::fromXml(QDomElement &dom_element)
//generate one on load, same treatment terminal uuids got when
//that field was introduced (see terminal1/terminal2 handling in
//toXml() below).
m_uuid = QUuid(dom_element.attribute("uuid", QUuid::createUuid().toString()));
m_uuid = QUuid(dom_element.attribute(QStringLiteral("uuid")));
if (m_uuid.isNull()) {
//Absent, empty or malformed: mint one. A null uuid is not a usable
//identity -- every conductor carrying one would collide with every
//other on the conductor table's primary key.
m_uuid = QUuid::createUuid();
}
setPos(dom_element.attribute("x", nullptr).toDouble(),
dom_element.attribute("y", nullptr).toDouble());