mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-15 01:54:14 +02:00
Save a .qetz without building the folios not touched (stage D4)
With QET_LAZY_FOLIOS=1, a project opened from a .qetz's index saves a .qetz without building the folios it never built, when building them would write the same: their parts are copied as they were and their rows of the document's engineering data from the project.sqlite they were read from (QetContainerDb::extract() with kept_from, QetContainer::split() with the old entries, pictures included). Whether a folio may be kept follows the rules of stage 5.5 (QETProject::toXml() with kept_parts): nothing project-wide changed since opening; a folio whose own data changed is built with its partners; after an edit, folios holding a table filled from the database are built; the partners still waiting of every built folio are built. Trusted only for a project opened from a format 3 index written by this version whose folios are named by their uuid. Format 3 names a folio by its uuid in the database (doc_meta folio_ids = uuid) when every folio has one of its own, so that a kept folio keeps its rows whatever its place; copies keep the rows' order (ORDER BY rowid). A folio not built keeps the name of its part until it is built (Diagram::deferredPart()). Measured, the 136-folio f2099 opened from its .qetz and saved as a .qetz: 4.75 s with no folio built, 33 s with every folio built; its 136 folio parts copied byte for byte; a kept save of a kept save is the same bytes. industrial.qetz untouched: 28 of its 47 folios not built are built to save (link chains, as in 5.5); after everyday edits on its busiest folio, 7 stay not built. tst_lazyfolios: an untouched .qetz saved without building, read back, holds the project; edits saved without building hold, read back, what the same edits saved with every folio built hold (read back too: a wire numbered from its potential is saved with no sequential numbers whichever the way -- reading it back renumbers it, a separate issue); fails when a kept folio's symbol information is not copied. Corpus, 342 projects: a .qetz saved without building, read and saved as .qet = eager = master on all 342. 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:
+39
-9
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "qetproject.h"
|
||||
#include "container/qetcontainer.h"
|
||||
#include "container/qetcontainerdb.h"
|
||||
|
||||
#include "ElementsCollection/xmlelementcollection.h"
|
||||
#include "autoNum/assignvariables.h"
|
||||
@@ -2293,8 +2294,12 @@ void QETProject::autoFolioNumberingSelectedFolios(int from,
|
||||
@brief QETProject::toXml
|
||||
@return un document XML representant le projet
|
||||
*/
|
||||
QDomDocument QETProject::toXml(QHash<int, QByteArray> *kept_folios)
|
||||
QDomDocument QETProject::toXml(QHash<int, QByteArray> *kept_folios, QStringList *kept_parts)
|
||||
{
|
||||
//With @p kept_parts, the same for a .qetz opened from its index: a
|
||||
//folio not built is written as <diagram qetz-kept-part="..."/>, its
|
||||
//part and its rows copied by QetContainer::split()
|
||||
//(stage D4)
|
||||
//With @p kept_folios, a folio not built (QET_LAZY_FOLIOS) is
|
||||
//written as a placeholder <diagram qet_kept_folio="n"/> and its text
|
||||
//as read from the file goes in kept_folios, for
|
||||
@@ -2308,8 +2313,8 @@ QDomDocument QETProject::toXml(QHash<int, QByteArray> *kept_folios)
|
||||
//is built with the folios its links reach, as when it is shown:
|
||||
//their saved texts can show its data (a report, its partner's
|
||||
//folio label).
|
||||
const bool keep = kept_folios && unloadedFolioCount()
|
||||
&& m_kept_folios_trusted && !m_kept_folios_stale;
|
||||
const bool keep = unloadedFolioCount() && !m_kept_folios_stale
|
||||
&& ((kept_folios && m_kept_folios_trusted) || (kept_parts && m_kept_parts_trusted));
|
||||
if (keep) {
|
||||
for (Diagram *diagram : std::as_const(m_diagrams_list))
|
||||
if (diagram->headerChanged())
|
||||
@@ -2423,6 +2428,15 @@ QDomDocument QETProject::toXml(QHash<int, QByteArray> *kept_folios)
|
||||
<< "["
|
||||
<< diagram
|
||||
<< "]";
|
||||
if (keep && !diagram->isLoaded() && kept_parts) {
|
||||
auto placeholder = xml_doc.createElement(QStringLiteral("diagram"));
|
||||
placeholder.setAttribute(QStringLiteral("qetz-kept-part"), diagram->deferredPart());
|
||||
placeholder.setAttribute(QStringLiteral("uuid"), diagram->uuid().toString());
|
||||
kept_parts->append(diagram->deferredPart());
|
||||
project_root.appendChild(placeholder);
|
||||
++order_num;
|
||||
continue;
|
||||
}
|
||||
if (keep && !diagram->isLoaded()) {
|
||||
auto placeholder = xml_doc.createElement(QStringLiteral("diagram"));
|
||||
placeholder.setAttribute(QStringLiteral("qet_kept_folio"), order_num);
|
||||
@@ -2520,7 +2534,7 @@ bool QETProject::isContainerPath(const QString &path)
|
||||
the whole archive is written.
|
||||
*/
|
||||
bool QETProject::writeContainer(const QDomDocument &project, const QString &path, QString *error,
|
||||
const QByteArray &index)
|
||||
const QByteArray &index, const QHash<QString, QByteArray> &kept_from)
|
||||
{
|
||||
//The project database, for opening without reading the folios
|
||||
//(stage D2), is in project.sqlite with the
|
||||
@@ -2528,7 +2542,7 @@ bool QETProject::writeContainer(const QDomDocument &project, const QString &path
|
||||
QList<QetZip::Entry> entries = QetContainer::split(
|
||||
project,
|
||||
QStringLiteral("QElectroTech %1").arg(QetVersion::currentVersion().toString()),
|
||||
error, index);
|
||||
error, index, kept_from);
|
||||
return !entries.isEmpty() && QetZip::write(path, entries, error);
|
||||
}
|
||||
|
||||
@@ -2541,8 +2555,12 @@ bool QETProject::writeContainer(const QDomDocument &project, const QString &path
|
||||
*/
|
||||
bool QETProject::writeContainerFile(const QString &path, QString *error)
|
||||
{
|
||||
const QDomDocument document = toXml(); //every folio built
|
||||
return writeContainer(document, path, error, containerIndex());
|
||||
//The folios not built, written as they were read, when that is
|
||||
//what building them would write (toXml()); every other folio built
|
||||
QStringList kept;
|
||||
const QDomDocument document = toXml(nullptr, &kept);
|
||||
return writeContainer(document, path, error, containerIndex(),
|
||||
kept.isEmpty() ? QHash<QString, QByteArray>() : m_container_files);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2552,7 +2570,11 @@ bool QETProject::writeContainerFile(const QString &path, QString *error)
|
||||
*/
|
||||
QByteArray QETProject::containerIndex()
|
||||
{
|
||||
loadFolios();
|
||||
//Opened from an index, the folios not built have their rows in the
|
||||
//database, whose keys are unique; the built ones are looked at
|
||||
if (!m_kept_parts_trusted) {
|
||||
loadFolios();
|
||||
}
|
||||
QSet<QUuid> seen;
|
||||
QList<std::pair<QUuid, QString>> headers;
|
||||
auto unique = [&seen](const QUuid &uuid) {
|
||||
@@ -2562,6 +2584,10 @@ QByteArray QETProject::containerIndex()
|
||||
};
|
||||
for (Diagram *diagram : std::as_const(m_diagrams_list)) {
|
||||
if (!unique(diagram->uuid())) return QByteArray();
|
||||
if (!diagram->isLoaded()) {
|
||||
headers.append({diagram->uuid(), diagram->headerXml()});
|
||||
continue;
|
||||
}
|
||||
for (Element *element : diagram->elements())
|
||||
if (!unique(element->uuid())) return QByteArray();
|
||||
for (Conductor *conductor : diagram->conductors())
|
||||
@@ -3224,9 +3250,13 @@ void QETProject::readProjectXml(QDomDocument &xml_project)
|
||||
for (Diagram *diagram : std::as_const(m_diagrams_list))
|
||||
if (!diagram->isLoaded() && diagram->keptText().isEmpty())
|
||||
m_kept_folios_trusted = false;
|
||||
m_kept_parts_trusted = m_opened_from_index && unloadedFolioCount() > 0
|
||||
&& m_project_qet_version == QetVersion::currentVersion()
|
||||
&& m_data_base.rowsFromDocument()
|
||||
&& QetContainerDb::foliosByUuid(m_container_files.value(QStringLiteral("project.sqlite")));
|
||||
m_kept_folios_stale = false;
|
||||
m_edited_since_open = false;
|
||||
if (m_kept_folios_trusted)
|
||||
if (m_kept_folios_trusted || m_kept_parts_trusted)
|
||||
for (Diagram *diagram : std::as_const(m_diagrams_list))
|
||||
diagram->rememberHeader();
|
||||
if (qEnvironmentVariableIntValue("QET_LAZY_FOLIOS_TRACE") == 1)
|
||||
|
||||
Reference in New Issue
Block a user