mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-15 01:54:14 +02:00
Save a new title, author or revision without building the folio (stage D5)
A folio not built whose own data changed was built to save, with the folios its links reach. When what changed is only title block fields nothing on a folio is computed from -- its title, author, date, revision index, version, file name, template; a formula reads the folio's label, plant, location, extra fields and grid -- its items as read are what building it would write: it is saved from them with its own data as it is now (Diagram::deferredXmlWithHeader()), .qet and .qetz alike, with the information of its symbols changed through the project database (or built, when one of those needs it). Any other change still builds it. 136-folio .qetz, revision index and author set on every folio by a script: 0.8 s, saved in 6.8 s, no folio built; with every folio built, the same file. tst_lazyfolios: a new revision on every folio of a .qet and of a .qetz saved as when built, building only the folios holding a table (fails, 47 built, when every change counts); a folio whose label changed is built (fails when none counts). ctest 96/96 eager and lazy; 342 corpus projects save the same in all four arms and export the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -830,6 +830,57 @@ QList<Element *> Diagram::buildSymbols(const QSet<QUuid> &uuids)
|
||||
return built;
|
||||
}
|
||||
|
||||
namespace {
|
||||
//The title block fields nothing on a folio is computed from: a formula
|
||||
//reads the folio's label, plant, location, extra fields and grid
|
||||
//(autonum::FormulaContext), none of these
|
||||
const QStringList ShownOnlyFields = {
|
||||
QStringLiteral("title"), QStringLiteral("author"), QStringLiteral("date"),
|
||||
QStringLiteral("indexrev"), QStringLiteral("version"), QStringLiteral("filename"),
|
||||
QStringLiteral("titleblocktemplate"), QStringLiteral("titleblocktemplateCollection")};
|
||||
|
||||
QString headerWithoutShownOnly(const QString &header)
|
||||
{
|
||||
QDomDocument document;
|
||||
document.setContent(header);
|
||||
QDomElement root = document.documentElement();
|
||||
for (const QString &field : ShownOnlyFields) root.removeAttribute(field);
|
||||
return document.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Diagram::headerChangeShowsOnly
|
||||
@return true if what changed in this folio's own data since it was read
|
||||
(headerChanged()) is only title block fields nothing on the folio is
|
||||
computed from (its title, author, date, revision, file name, template):
|
||||
its items, as read, are what building it would write
|
||||
*/
|
||||
bool Diagram::headerChangeShowsOnly()
|
||||
{
|
||||
return headerWithoutShownOnly(headerXml()) == headerWithoutShownOnly(m_opened_header);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Diagram::deferredXmlWithHeader
|
||||
@return this folio, not built, as it saves: its own data as it is now
|
||||
(writeHeader()) and its items as read (deferredXml()), in @p document --
|
||||
when its items are what building it would write (headerChangeShowsOnly())
|
||||
*/
|
||||
QDomElement Diagram::deferredXmlWithHeader(QDomDocument &document)
|
||||
{
|
||||
QDomElement folio = document.createElement(QStringLiteral("diagram"));
|
||||
writeHeader(document, folio);
|
||||
QSet<QString> header_children;
|
||||
for (QDomElement child = folio.firstChildElement() ; !child.isNull() ; child = child.nextSiblingElement())
|
||||
header_children.insert(child.tagName());
|
||||
const QDomElement items = deferredXml();
|
||||
for (QDomElement child = items.firstChildElement() ; !child.isNull() ; child = child.nextSiblingElement())
|
||||
if (!header_children.contains(child.tagName()))
|
||||
folio.appendChild(document.importNode(child, true));
|
||||
return folio;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Diagram::deferredXml
|
||||
@return the XML of this folio's items while they are not built: kept
|
||||
|
||||
@@ -240,6 +240,8 @@ class Diagram : public QGraphicsScene
|
||||
/// headerChanged() (QETProject::toXml())
|
||||
void rememberHeader() {m_opened_header = headerXml();}
|
||||
bool headerChanged() {return headerXml() != m_opened_header;}
|
||||
bool headerChangeShowsOnly();
|
||||
QDomElement deferredXmlWithHeader(QDomDocument &document);
|
||||
void ensureLoaded();
|
||||
bool buildDeferred();
|
||||
//The last argument is only for a copy fragment: when it is
|
||||
|
||||
+28
-2
@@ -2374,9 +2374,17 @@ QDomDocument QETProject::toXml(QHash<int, QByteArray> *kept_folios, QStringList
|
||||
changed << diagram;
|
||||
}
|
||||
buildFolios(changed);
|
||||
for (Diagram *diagram : std::as_const(m_diagrams_list))
|
||||
if (diagram->headerChanged())
|
||||
//-- unless it changed only in what nothing is computed from (its
|
||||
//title, date, revision...): written from its items as read
|
||||
//(Diagram::deferredXmlWithHeader())
|
||||
for (Diagram *diagram : std::as_const(m_diagrams_list)) {
|
||||
if (!diagram->headerChanged()) continue;
|
||||
bool edits_need_build = false;
|
||||
if (!diagram->isLoaded())
|
||||
m_data_base.unbuiltEditsOnFolio(diagram->uuid(), &edits_need_build);
|
||||
if (diagram->isLoaded() || !diagram->headerChangeShowsOnly() || edits_need_build)
|
||||
buildFolioToShow(diagram);
|
||||
}
|
||||
//A table filled from the database saves the size its rows
|
||||
//give it, which any edit can change
|
||||
if (m_edited_since_open)
|
||||
@@ -2490,6 +2498,24 @@ QDomDocument QETProject::toXml(QHash<int, QByteArray> *kept_folios, QStringList
|
||||
<< "["
|
||||
<< diagram
|
||||
<< "]";
|
||||
if (keep && !diagram->isLoaded() && diagram->headerChanged()) {
|
||||
QDomElement xml_diagram = diagram->deferredXmlWithHeader(xml_doc);
|
||||
//Its symbols whose information changed while it was not built
|
||||
const QHash<QUuid, DiagramContext> edits = m_data_base.unbuiltEditsOnFolio(diagram->uuid());
|
||||
for (const QDomElement &list : QET::findInDomElement(xml_diagram, QStringLiteral("elements")))
|
||||
for (QDomElement element = list.firstChildElement(QStringLiteral("element")) ; !element.isNull() ;
|
||||
element = element.nextSiblingElement(QStringLiteral("element"))) {
|
||||
const auto edit = edits.constFind(QUuid(element.attribute(QStringLiteral("uuid"))));
|
||||
if (edit == edits.constEnd()) continue;
|
||||
QDomElement information = xml_doc.createElement(QStringLiteral("elementInformations"));
|
||||
edit->toXml(information, QStringLiteral("elementInformation"));
|
||||
const QDomElement old_information = element.firstChildElement(QStringLiteral("elementInformations"));
|
||||
element.replaceChild(information, old_information); //it has one (unbuiltEditsOnFolio())
|
||||
}
|
||||
xml_diagram.setAttribute("order", order_num ++);
|
||||
project_root.appendChild(xml_diagram);
|
||||
continue;
|
||||
}
|
||||
if (keep && !diagram->isLoaded() && kept_parts) {
|
||||
auto placeholder = xml_doc.createElement(QStringLiteral("diagram"));
|
||||
placeholder.setAttribute(QStringLiteral("qetz-kept-part"), diagram->deferredPart());
|
||||
|
||||
Reference in New Issue
Block a user