mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-15 10:04:13 +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:
@@ -22,6 +22,7 @@
|
||||
#include <QHash>
|
||||
#include <QMap>
|
||||
#include <QSet>
|
||||
#include <QRegularExpression>
|
||||
|
||||
const char QetContainer::MimeType[] = "application/x-qelectrotech-project+zip";
|
||||
|
||||
@@ -228,7 +229,8 @@ void QetContainer::dropComputed(QDomElement diagram, bool terminal_lists)
|
||||
set if @p project is not a project
|
||||
*/
|
||||
QList<QetZip::Entry> QetContainer::split(const QDomDocument &project, const QString &writer,
|
||||
QString *error, const QByteArray &index)
|
||||
QString *error, const QByteArray &index,
|
||||
const QHash<QString, QByteArray> &kept_from)
|
||||
{
|
||||
QDomDocument document = project.cloneNode(true).toDocument();
|
||||
QDomElement root = document.documentElement();
|
||||
@@ -238,7 +240,11 @@ QList<QetZip::Entry> QetContainer::split(const QDomDocument &project, const QStr
|
||||
}
|
||||
|
||||
//The engineering data out of the document, into project.sqlite
|
||||
const QByteArray database = QetContainerDb::extract(root, error, index);
|
||||
//A folio written as it was read (<diagram qetz-kept-part="..."/>,
|
||||
//stage D4) keeps its part and, through
|
||||
//@p kept_from's project.sqlite, its rows
|
||||
const QByteArray database = QetContainerDb::extract(
|
||||
root, error, index, kept_from.value(QStringLiteral("project.sqlite")));
|
||||
if (database.isEmpty())
|
||||
return {};
|
||||
|
||||
@@ -247,11 +253,35 @@ 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());
|
||||
|
||||
//The parts of the folios kept as they were, and their pictures
|
||||
QMap<QString, QByteArray> pictures; //name -> png, once each
|
||||
for (QDomElement diagram : childElements(root, QStringLiteral("diagram")))
|
||||
{
|
||||
const QString kept = diagram.attribute(QStringLiteral("qetz-kept-part"));
|
||||
if (kept.isEmpty()) continue;
|
||||
if (!kept_from.contains(kept)) {
|
||||
setError(error, QStringLiteral("the part \"%1\" of a folio kept as it was is missing").arg(kept));
|
||||
return {};
|
||||
}
|
||||
taken.insert(kept);
|
||||
const QByteArray part = kept_from.value(kept);
|
||||
static const QRegularExpression image_file(QStringLiteral("%1=\"(images/[^\"]+)\"").arg(ImageFileAttribute));
|
||||
for (const auto &match : image_file.globalMatch(QString::fromUtf8(part))) {
|
||||
const QString name = match.captured(1);
|
||||
if (!kept_from.contains(name)) {
|
||||
setError(error, QStringLiteral("the picture \"%1\" of a folio kept as it was is missing").arg(name));
|
||||
return {};
|
||||
}
|
||||
pictures.insert(name, kept_from.value(name));
|
||||
}
|
||||
parts.append(QetZip::Entry{kept, part, true});
|
||||
root.replaceChild(placeholder(document, kept), diagram);
|
||||
}
|
||||
|
||||
for (QDomElement diagram : childElements(root, QStringLiteral("diagram")))
|
||||
{
|
||||
++folio;
|
||||
|
||||
Reference in New Issue
Block a user