A .qetz keeps nothing QElectroTech computes in its folio files (stage D3c)

Format 3 folio files lose what building a folio computes
(QetContainer::dropComputed()): a wire's description of its ends
(element1_label, element1_name, element1_linked, terminalname1 and the
same for end 2), the content of a symbol text showing the symbol's
information or a composition of it, and -- when the project database's
index is written, every symbol with a uuid of its own -- a symbol's list
of its terminals.

What may go was found by test, not by reading: on 342 projects saved by
this version, each kind taken out of the file, the project opened and
saved: the wire ends came back in all 244 that had them, the symbol texts
in all 201, the terminal lists in 305 of 306 -- not in the file whose
symbols share a uuid (#1408), where wires find their ends by them; such a
project gets no index, so it keeps them.

Stays, for now: labels made from a formula and wire numbers made from one,
in the database (opening from the index and numbering read them), and a
table's size (the user's as much as computed).

tst_qetcontainer compares a joined document with the original less what is
computed, and computedNotKept checks a file holding both kinds (one filled
in by the test) loses them -- it fails when nothing is dropped. Through
QElectroTech, 342 projects: a .qetz opened from its index and saved as .qet
= eager = master; every folio of industrial and f2099 drawn and linked as
eager (f2099 but its 3 render-noise folios). ctest 96/96 with and without
QET_LAZY_FOLIOS=1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-11 19:57:43 +13:00
parent 2f98872d7a
commit 8ea051acfc
3 changed files with 112 additions and 3 deletions
+60
View File
@@ -93,6 +93,19 @@ QList<QDomElement> childElements(const QDomElement &parent, const QString &tag)
return list;
}
//An element and the text nodes on either side of it out of its parent,
//one text node left where they were, so nothing is read twice
void removeElement(QDomElement e)
{
QDomNode parent = e.parentNode();
QDomNode before = e.previousSibling(), after = e.nextSibling();
parent.removeChild(e);
if (before.isText() && after.isText()) {
before.setNodeValue(before.nodeValue() + after.nodeValue());
parent.removeChild(after);
}
}
//The collection's symbol definitions, each to elements/<categories>/<name>
void splitCollection(QDomDocument &document, const QDomElement &category, const QString &path,
QList<QetZip::Entry> *parts, QSet<QString> *taken)
@@ -164,6 +177,49 @@ bool QetContainer::readDocument(const QByteArray &content, QDomDocument *documen
&& join(entries, document, error);
}
/**
@brief QetContainer::dropComputed
Take out of the folio @p diagram what QElectroTech computes when it
builds the folio (stage D3c): a wire's description of
its ends (element1_label, element1_name, element1_linked, terminalname1,
and the same for end 2), a symbol text's content where it shows the
symbol's information or a composition of it, and -- with
@p terminal_lists, when every symbol has a uuid of its own -- a symbol's
list of its terminals. Checked on 342 projects: opened and saved, each
comes back as it was, but the terminal lists of a file whose symbols
share a uuid (F100), where wires find their ends by them.
*/
void QetContainer::dropComputed(QDomElement diagram, bool terminal_lists)
{
for (QDomElement list : childElements(diagram, QStringLiteral("conductors")))
for (QDomElement wire : childElements(list, QStringLiteral("conductor")))
for (const char *end : {"1", "2"})
for (const char *name : {"element%1_label", "element%1_name", "element%1_linked",
"terminalname%1"})
wire.removeAttribute(QString::fromLatin1(name).arg(QLatin1String(end)));
for (QDomElement list : childElements(diagram, QStringLiteral("elements")))
{
for (QDomElement element : childElements(list, QStringLiteral("element")))
{
if (terminal_lists)
for (QDomElement terminals : childElements(element, QStringLiteral("terminals")))
removeElement(terminals);
for (QDomElement texts : childElements(element, QStringLiteral("dynamic_texts")))
{
for (QDomElement text : childElements(texts, QStringLiteral("dynamic_elmt_text")))
{
const QString from = text.attribute(QStringLiteral("text_from"));
if (from != QLatin1String("ElementInfo") && from != QLatin1String("CompositeText"))
continue;
for (QDomElement content : childElements(text, QStringLiteral("text")))
while (content.hasChildNodes())
content.removeChild(content.firstChild());
}
}
}
}
}
/**
@brief QetContainer::split
@param project : the project document, as QETProject::toXml() makes it
@@ -192,6 +248,10 @@ QList<QetZip::Entry> QetContainer::split(const QDomDocument &project, const QStr
//Folios, each with its pictures taken out
int folio = 0;
QMap<QString, QByteArray> pictures; //name -> png, once each
//Nothing QElectroTech computes is kept (format 3)
for (QDomElement diagram : childElements(root, QStringLiteral("diagram")))
dropComputed(diagram, !index.isEmpty());
for (QDomElement diagram : childElements(root, QStringLiteral("diagram")))
{
++folio;
+2
View File
@@ -60,6 +60,8 @@ namespace QetContainer
bool readFolio(const QHash<QString, QByteArray> &files, const QString &file,
QDomDocument *folio, QString *error = nullptr);
/// Take what QElectroTech computes out of a folio (format 3)
void dropComputed(QDomElement diagram, bool terminal_lists);
/// Parse @p xml as a .qet is read (QETProject::openFile)
bool parse(const QByteArray &xml, QDomDocument *document, QString *error = nullptr);
/// true if @p content is a zip, so a .qetz rather than a .qet