Keep the symbols and wires a folio cannot load, and save them back

Opening a project dropped, with only a debug line, a symbol whose
definition could not be found (missing from the project's collection and
from the library) and every wire on it; and a wire whose terminal could
not be matched, after the symbol's definition was redrawn. The next save
wrote the project without them. One save of a forum upload whose
collection was incomplete kept 1 of 219 symbols and none of its 299 wires.

A folio now keeps what it could not load as it was read
(Diagram::m_kept_symbols, m_kept_wires) and writes it back when it is
saved whole (Diagram::writeKept()):
- a symbol, its terminals given ids after those of the folio's symbols;
- a wire, an end found written from its terminal as Conductor::toXml()
  does, an end not found as the symbol and terminal uuids it names; for a
  wire saved by legacy ids, the terminal's uuid derived from where it was
  saved (Element::savedTerminalUuid(), out of matchMovedTerminals()), so
  it joins again once the definition has it there. A wire whose ends
  cannot be read, or an end naming no terminal of the file, is kept so
  that it joins nothing.
A symbol kept counts as waiting (projectDataBase::waitingSymbols()), so a
partner keeps its link to it. The open warning now lists the symbols not
loaded too, and says both are kept.

Once the definition is back, the symbol and its wires are built again:
741.qet with one transistor definition removed (8 symbols, 33 wires on
them) saves all 67 wires, and with the definition put back opens with
all 65 symbols and 67 wires, the same folio as before.

tst_resaveunchanged::unloadableItemsKept: fixtures/coil_contact_wired.qet
(coil, linked contact, two wires; built with the script API) with the
coil's definition removed, or the contact's terminals moved and given new
uuids: both symbols, wires and links saved, a second save the same, and
the coil's definition put back gives the undamaged project's symbols and
wires. Fails on master (1 symbol; 0 wires).

FINDINGS F127, F128.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-19 16:45:55 +13:00
parent 3abaf21302
commit 0bcd0ca4b6
9 changed files with 823 additions and 47 deletions
+30 -7
View File
@@ -2262,15 +2262,38 @@ bool QETDiagramEditor::openAndAddProject(
);
}
//Report wires left out of the load because a terminal they join
//was not found: they would otherwise vanish on the next save
//without the user ever being told.
QStringList lost_wires;
//Report the elements and wires left out of the load: an element
//whose definition is missing, a wire whose terminal was not found.
//They are kept in the file as they were (F127, F128), but are not
//shown.
QStringList lost_elements, lost_wires;
for (Diagram *diagram : project->folios()) {
if (!diagram->isLoaded()) continue;
for (const QString &element : diagram->symbolsNotLoaded())
lost_elements << tr("Sheet %1: %2").arg(diagram->folioIndex() + 1).arg(element);
}
for (Diagram *diagram : project->foliosWithWiresNotReconnected()) {
for (const QString &wire : diagram->wiresNotReconnected()) {
lost_wires << tr("Sheet %1: %2").arg(diagram->folioIndex() + 1).arg(wire);
}
}
if (interactive && !lost_elements.isEmpty())
{
QMessageBox box(QMessageBox::Warning,
tr("Elements not loaded", "message box title"),
tr("%n elements could not be loaded: their definition is "
"missing from the project and from the collections.\n"
"\n"
"They are not shown, but they are kept in the file as they "
"are, with their conductors, and come back once their "
"definition is available again.",
"message box content",
lost_elements.size()),
QMessageBox::Ok,
this);
box.setDetailedText(lost_elements.join(QLatin1Char('\n')));
box.exec();
}
if (interactive && !lost_wires.isEmpty())
{
QMessageBox box(QMessageBox::Warning,
@@ -2280,9 +2303,9 @@ bool QETDiagramEditor::openAndAddProject(
"was probably replaced by another one with different "
"terminals.\n"
"\n"
"If you save the project, these conductors will disappear "
"from the file. Close it without saving to keep the file as "
"it is.",
"They are not shown, but they are kept in the file as they "
"are, and join their terminals again once the definition "
"has them where they were.",
"message box content",
lost_wires.size()),
QMessageBox::Ok,