mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-15 01:54:14 +02:00
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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -69,6 +69,18 @@ class tst_qetcontainer : public QObject
|
||||
return QetContainer::split(*original, QStringLiteral("tst_qetcontainer"), &error);
|
||||
}
|
||||
|
||||
//@p document without what QElectroTech computes, which a .qetz
|
||||
//does not keep (format 3); tst_resaveunchanged checks that
|
||||
//QElectroTech gives it back
|
||||
static QDomDocument withoutComputed(const QDomDocument &document)
|
||||
{
|
||||
QDomDocument copy = document.cloneNode(true).toDocument();
|
||||
for (QDomElement diagram = copy.documentElement().firstChildElement(QStringLiteral("diagram"));
|
||||
!diagram.isNull() ; diagram = diagram.nextSiblingElement(QStringLiteral("diagram")))
|
||||
QetContainer::dropComputed(diagram, false);
|
||||
return copy;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void sameDocumentBack_data()
|
||||
{
|
||||
@@ -100,7 +112,8 @@ private slots:
|
||||
QVERIFY2(QetZip::fromBytes(QetZip::toBytes(entries, &error), &unzipped, &error), qPrintable(error));
|
||||
QDomDocument back;
|
||||
QVERIFY2(QetContainer::join(unzipped, &back, &error), qPrintable(error));
|
||||
const QString d = difference(original.documentElement(), back.documentElement(), QString());
|
||||
const QString d = difference(withoutComputed(original).documentElement(),
|
||||
back.documentElement(), QString());
|
||||
QVERIFY2(d.isEmpty(), qPrintable(d));
|
||||
}
|
||||
|
||||
@@ -136,7 +149,9 @@ private slots:
|
||||
|
||||
// The engineering data is in project.sqlite and nowhere else: the folio
|
||||
// files hold no symbol information, links, wire numbers or title-block
|
||||
// fields, and the database holds them all (industrial.qet: 50 folios).
|
||||
// fields, nor what QElectroTech computes from them (a wire's
|
||||
// description of its ends, a symbol text showing its information), and
|
||||
// the database holds them all (industrial.qet: 50 folios).
|
||||
void databaseHoldsTheData()
|
||||
{
|
||||
QDomDocument original;
|
||||
@@ -181,6 +196,37 @@ private slots:
|
||||
sqlite3_close(db);
|
||||
}
|
||||
|
||||
// Nor does a folio file hold what QElectroTech computes (format 3): a
|
||||
// wire's description of its ends, a symbol text showing its information.
|
||||
// A file holding both, so that the check can fail.
|
||||
void computedNotKept()
|
||||
{
|
||||
QDomDocument original;
|
||||
QString error;
|
||||
QVERIFY(QetContainer::parse(read(QStringLiteral(QET_EXAMPLES_DIR "/schema_unifilaire_voltaique2.qet")),
|
||||
&original, &error));
|
||||
const QDomNodeList texts = original.elementsByTagName(QStringLiteral("dynamic_elmt_text"));
|
||||
bool filled = false;
|
||||
for (int i = 0 ; i < texts.size() && !filled ; ++i) {
|
||||
QDomElement text = texts.at(i).toElement();
|
||||
if (text.attribute(QStringLiteral("text_from")) != QLatin1String("ElementInfo")) continue;
|
||||
QDomElement content = text.firstChildElement(QStringLiteral("text"));
|
||||
while (content.hasChildNodes()) content.removeChild(content.firstChild());
|
||||
content.appendChild(original.createTextNode(QStringLiteral("COMPUTED-LABEL")));
|
||||
filled = true;
|
||||
}
|
||||
QVERIFY(filled);
|
||||
QVERIFY(original.toString().contains(QStringLiteral("element1_label=")));
|
||||
const QList<QetZip::Entry> entries = QetContainer::split(original, QString(), &error);
|
||||
QVERIFY2(!entries.isEmpty(), qPrintable(error));
|
||||
for (const QetZip::Entry &e : entries) {
|
||||
if (!e.name.startsWith(QStringLiteral("folios/"))) continue;
|
||||
QVERIFY2(!e.data.contains("element1_label=") && !e.data.contains("terminalname2="),
|
||||
qPrintable(e.name));
|
||||
QVERIFY2(!e.data.contains("COMPUTED-LABEL"), qPrintable(e.name));
|
||||
}
|
||||
}
|
||||
|
||||
// Terminal strips move into the database, and come back exactly:
|
||||
// industrial.qet with two strips on its own terminal symbols, parsed as
|
||||
// a save leaves it (no whitespace text).
|
||||
@@ -217,7 +263,8 @@ private slots:
|
||||
QVERIFY2(!e.data.contains("<terminal_strip>"), "the strips stayed in project.xml");
|
||||
QDomDocument back;
|
||||
QVERIFY2(QetContainer::join(entries, &back, &error), qPrintable(error));
|
||||
const QString d = difference(original.documentElement(), back.documentElement(), QString());
|
||||
const QString d = difference(withoutComputed(original).documentElement(),
|
||||
back.documentElement(), QString());
|
||||
QVERIFY2(d.isEmpty(), qPrintable(d));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user