Build folios only when needed, by default (stage D6)

Every project now opens without building its folios; a folio is built
when it is shown or something needs its items (QETProject::lazyFolios()).
QET_LAZY_FOLIOS is gone; QET_EAGER_FOLIOS=1 builds every folio on
opening, as before, for comparisons and troubleshooting. Comments that
named the old variable now say "lazy folios"; the tests switch modes
with the new one.

The first save of a .qet as .qetz still builds every folio: a .qet does
not say which program wrote it, so its folios are written again rather
than copied. A .qetz opens and saves without building.

ctest 96/96 by default and with QET_EAGER_FOLIOS=1; 342 corpus projects
save the same in all four arms and export the same. In the GUI
(qet-gui-dialog): a 136-folio .qetz opens with no folio built, shows
folios 1 to 4, saves building none, the save = the original but the time
spent in it; a .qet opens lazily, saves as a .qetz beside it after the
notice, the .qet unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-12 19:27:22 +13:00
parent b151f52428
commit 5c4fa8fadf
24 changed files with 104 additions and 87 deletions
+1 -1
View File
@@ -1011,7 +1011,7 @@ bool TerminalStrip::fromXml(QDomElement &xml_element)
auto xml_layout = xml_element.firstChildElement(QStringLiteral("layout"));
if (!xml_layout.isNull())
{
//The folios holding its terminals are built (QET_LAZY_FOLIOS):
//The folios holding its terminals are built (lazy folios):
//a strip is read with the project, before the database could
//tell where any symbol is
QSet<QUuid> terminals;
+3 -3
View File
@@ -878,7 +878,7 @@ int resaveProject(QETProject &project, const QString &output)
out << "Re-saved project -> " << output << "\n";
return 0;
}
//Folios not built (QET_LAZY_FOLIOS) written as read when that is
//Folios not built (lazy folios) written as read when that is
//what building them would write (QETProject::toXml())
QHash<int, QByteArray> kept_folios;
const QDomDocument doc = project.toXml(&kept_folios);
@@ -973,8 +973,8 @@ int setTitleBlock(QETProject &project, const QString &output,
return 1;
}
} else {
//Folios not built (QET_LAZY_FOLIOS) written as read when that is
//what building them would write (QETProject::toXml())
//Folios not built (lazy folios) written as read when that
//is what building them would write (QETProject::toXml())
QHash<int, QByteArray> kept_folios;
const QDomDocument doc = project.toXml(&kept_folios);
QFile file(output);
+1 -1
View File
@@ -118,7 +118,7 @@ void ConductorNumExport::fillHash()
auto count = [this](const QString &num) {
m_hash.insert(num, m_hash.value(num, 0) + 1);
};
//The folios not built (QET_LAZY_FOLIOS): their wires from the
//The folios not built (lazy folios): their wires from the
//project database, by the same rules
QList<QUuid> unbuilt;
for (Diagram *d : m_project->folios())
+11 -11
View File
@@ -141,7 +141,7 @@ void projectDataBase::updateDB()
@brief projectDataBase::keepUnbuiltFolioRows
Before the tables are rebuilt from the folios: keep the element,
element_info, terminal, conductor and link rows of the folios not built
yet (QET_LAZY_FOLIOS). They came from the document, nothing of those
yet (lazy folios). They came from the document, nothing of those
folios can have changed since, and the rebuild puts them back where
each folio comes (restoreKeptRows()). Nothing to do when every folio
is built.
@@ -455,7 +455,7 @@ bool projectDataBase::populateFromDocument(const QDomDocument &document, QString
//The folios, in the order the project read them (readDiagramsXml()),
//each with its saved uuid -- the one the built folio has.
const QDomNodeList diagram_nodes = document.elementsByTagName(QStringLiteral("diagram"));
//Built or not (QET_LAZY_FOLIOS): only their uuids are read, and the
//Built or not (lazy folios): only their uuids are read, and the
//conductors of those built
const QList<Diagram *> diagrams = m_project->folios();
if (diagram_nodes.size() != diagrams.size()) {
@@ -1215,7 +1215,7 @@ QSet<QUuid> projectDataBase::foliosWithUnjoinedWires() const
@brief projectDataBase::elementTypesOnFolios
@return the kind (ElementData::typeToString()) of every symbol on the
folios @p folios, by uuid, read from the element table as it is: for
folios not built yet (QET_LAZY_FOLIOS) its rows came from the document
folios not built yet (lazy folios) its rows came from the document
and nothing can have changed them. A symbol whose definition was not
found has no row.
*/
@@ -1381,7 +1381,7 @@ autonum::sequentialNumbers projectDataBase::sequenceFromValue(const QVariant &va
/**
@brief projectDataBase::canEditUnbuilt
@return true if the information of the symbol @p element can be changed
through the store alone, its folio not built (QET_LAZY_FOLIOS): it is
through the store alone, its folio not built (lazy folios): it is
placed once, on a folio not built, and nothing else shows its
information -- no symbol built (alone or with its folio) holds it, no
partner is linked to it, and it has no label formula, which could read
@@ -1522,7 +1522,7 @@ bool projectDataBase::setPlacedElementInformation(const QUuid &element, const Di
@brief projectDataBase::folioUuidsOfElements
@return the uuids of the folios the symbols @p elements are on, read
from the element table as it is, without bringing it up to date: for a
symbol on a folio not built yet (QET_LAZY_FOLIOS) its row came from the
symbol on a folio not built yet (lazy folios) its row came from the
document and nothing can have changed it.
*/
QSet<QUuid> projectDataBase::folioUuidsOfElements(const QSet<QUuid> &elements) const
@@ -1660,7 +1660,7 @@ QSqlQuery projectDataBase::newQuery(const QString &query, QString *error) {
//storeConductorProperties().
//The drawing tables hold what only built items know (a text's
//laid-out size, a picture's pixels): with folios not built yet
//(QET_LAZY_FOLIOS) a read of them builds those first. Every other
//(lazy folios) a read of them builds those first. Every other
//table was filled from the document.
static const QRegularExpression drawing_tables(
QStringLiteral("\\b(shape|independent_text|image)\\b"),
@@ -1730,7 +1730,7 @@ int projectDataBase::excludedConductorCount() const
return 0;
}
//A folio not built (QET_LAZY_FOLIOS) has none: reading a wire
//A folio not built (lazy folios) has none: reading a wire
//drops it unless both its ends are found (Conductor::fromXml())
int count = 0;
for (auto *diagram : m_project->builtFolios())
@@ -1918,7 +1918,7 @@ void projectDataBase::flushElementPositions()
/**
@brief projectDataBase::updateFolioPositions
Write every folio's position and folio number again, after a folio was
added, removed or moved. A folio not built yet (QET_LAZY_FOLIOS) has
added, removed or moved. A folio not built yet (lazy folios) has
its position and title block already: it is not built for this.
*/
void projectDataBase::updateFolioPositions()
@@ -2583,7 +2583,7 @@ void projectDataBase::populateDrawingItemTables()
//Queued directly, not through addDrawingItem(): every one of them
//came onto its folio through Diagram::addItem(), which connected it
//already, and a full rebuild runs on every load. A folio not built
//yet (QET_LAZY_FOLIOS) has none: its items write their rows as it
//yet (lazy folios) has none: its items write their rows as it
//is built.
for (auto diagram : m_project->folios())
{
@@ -3887,7 +3887,7 @@ void projectDataBase::prefillFromDocument(const QDomDocument &document)
@brief projectDataBase::endPrefill
The folios are built: compare what prefillFromDocument() stored with
what building stored, and forget what nothing was placed for -- unless
@p keep_unplaced, when some folios are not built yet (QET_LAZY_FOLIOS):
@p keep_unplaced, when some folios are not built yet (lazy folios):
the store then answers for their items until they are.
*/
void projectDataBase::endPrefill(bool keep_unplaced)
@@ -4099,7 +4099,7 @@ void projectDataBase::flushLinks()
qDebug() << "projectDataBase::flushLinks insert error : " << insert.lastError();
}
}
//Partners on a folio not built (QET_LAZY_FOLIOS), which it will
//Partners on a folio not built (lazy folios), which it will
//be linked to once that folio is
for (const auto &waiting : element->waitingLinks())
{
+2 -2
View File
@@ -160,7 +160,7 @@ class projectDataBase : public QObject
//they are, say how many of those values building agreed with.
void prefillFromDocument(const QDomDocument &document);
void endPrefill(bool keep_unplaced = false);
//A folio of a project opened with QET_LAZY_FOLIOS is being built:
//A folio of a project opened with lazy folios is being built:
//its rows came from the document already, so none are written
//and the database is not marked changed
void setBuildingFolio(bool building);
@@ -357,7 +357,7 @@ class projectDataBase : public QObject
//The folios whose rows a rebuild keeps (keepUnbuiltFolioRows())
QSet<Diagram *> m_kept_folios;
//The tables' rows were filled from the document: those of a
//folio not built yet are right (QET_LAZY_FOLIOS)
//folio not built yet are right (lazy folios)
bool m_rows_from_document = false;
void keepUnbuiltFolioRows();
void restoreKeptRows(const QString &table, Diagram *folio, const QString &where);
+5 -5
View File
@@ -772,7 +772,7 @@ void Diagram::keyReleaseEvent(QKeyEvent *e)
/**
@brief Diagram::ensureLoaded
Build this folio's items from the XML kept when the project was
opened with QET_LAZY_FOLIOS, and do for them what opening does for
opened with lazy folios, and do for them what opening does for
every folio's (QETProject::folioLoaded()). Nothing for a folio built
already.
*/
@@ -790,7 +790,7 @@ void Diagram::ensureLoaded()
/**
@brief Diagram::buildSymbols
Build, of this folio not built yet (QET_LAZY_FOLIOS), the symbols
Build, of this folio not built yet (lazy folios), the symbols
@p uuids only -- partners a shown folio draws from -- and keep them for
when the folio is built (stage D5b). They belong to the
folio's scene; the folio stays not built.
@@ -1247,7 +1247,7 @@ QList < QSet <Conductor *> > Diagram::potentials()
\~French Un Document XML (QDomDocument)
*/
QDomDocument Diagram::toXml(bool whole_content, bool is_copy_command) {
//A folio of a project opened with QET_LAZY_FOLIOS is written from
//A folio of a project opened with lazy folios is written from
//its built items (QETProject::toXml() may write one not built as
//it was read instead)
ensureLoaded();
@@ -1360,7 +1360,7 @@ QDomDocument Diagram::toXml(bool whole_content, bool is_copy_command) {
//Wires that tie on their ends (common: several from one terminal)
//keep the order they were made in, which for a project's is its
//file's -- the order the scene gave them so far, except for a folio
//built late (QET_LAZY_FOLIOS), whose scene order differed
//built late (lazy folios), whose scene order differed
std::stable_sort(list_conductors.begin(), list_conductors.end(),
[](Conductor *a, Conductor *b) {
const QString ka = conductorSortKey(a), kb = conductorSortKey(b);
@@ -2042,7 +2042,7 @@ bool Diagram::fromXml(QDomElement &document,
return(true);
}
//A project opened with QET_LAZY_FOLIOS builds a folio's items when
//A project opened with lazy folios builds a folio's items when
//they are first needed: until then the folio has what it says
//about itself (uuid, title block, border, numbering) and keeps its
//XML, which belongs to the project's document.
+1 -1
View File
@@ -217,7 +217,7 @@ class Diagram : public QGraphicsScene
bool = true,
DiagramContent * = nullptr);
/// false while this folio's items wait in its XML to be
/// built (QET_LAZY_FOLIOS)
/// built (lazy folios)
bool isLoaded() const {return m_deferred.isNull() && m_deferred_part.isEmpty();}
QDomElement deferredXml();
/// The folio's items are in the part @p file of the .qetz the
+1 -1
View File
@@ -108,7 +108,7 @@ class DiagramContent
QList<Conductor *> m_potential_candidates;
/// One wire of each potential, worked out when first asked:
/// following a potential goes through folio reports to other
/// folios, building those not built yet (QET_LAZY_FOLIOS)
/// folios, building those not built yet (lazy folios)
mutable std::optional<QList<Conductor *>> m_potential_conductors;
};
QDebug &operator<<(QDebug, DiagramContent &);
+1 -1
View File
@@ -1649,7 +1649,7 @@ void DiagramView::editDiagramProperties()
@brief DiagramView::buildFolio
Build the items of the folio this view shows, and those of the folios
its cross-references need, if the project was opened without them
(QET_LAZY_FOLIOS); then fit the view to them.
(lazy folios); then fit the view to them.
*/
void DiagramView::buildFolio()
{
+2 -2
View File
@@ -55,7 +55,7 @@ ElementProvider::ElementProvider(const QList<Diagram *> &diagrams) :
@brief ElementProvider::folios
@return the folios to search for symbols of the kinds @p kinds (free
ones only if @p free_only). For a project, the folios not built yet
(QET_LAZY_FOLIOS) holding such a symbol are built first, and only them
(lazy folios) holding such a symbol are built first, and only them
(QETProject::buildFoliosHolding()).
*/
QList<Diagram *> ElementProvider::folios(ElementData::Types kinds, bool free_only) const
@@ -98,7 +98,7 @@ QVector <QPointer<Element>> ElementProvider::freeElement(ElementData::Types filt
QList<Element *> elmt_list;
const QList<Diagram *> searched = folios(filter, true);
//A symbol whose saved partner is on a folio not built yet
//(QET_LAZY_FOLIOS) is not linked yet, but is not free: it will be
//(lazy folios) is not linked yet, but is not free: it will be
const QSet<QUuid> waiting = m_project ? m_project->symbolsOnUnbuiltFolios()
: QSet<QUuid>();
+1 -1
View File
@@ -55,7 +55,7 @@ class ElementProvider
QList <Diagram *> m_diagram_list;
//Searching a project: its folios are asked for when searched,
//so that a project opened with QET_LAZY_FOLIOS builds only
//so that a project opened with lazy folios builds only
//those a search can find something on
QETProject *m_project = nullptr;
Diagram *m_excluded = nullptr;
+1 -1
View File
@@ -1257,7 +1257,7 @@ void ProjectView::rebuildDiagramsMap()
*/
void ProjectView::tabChanged(int tab_id)
{
//A folio opened without its items (QET_LAZY_FOLIOS) is built when
//A folio opened without its items (lazy folios) is built when
//its tab is first shown. Read the tab itself: the first tab is
//shown while loadDiagrams() is still filling m_diagram_ids
if (auto dv = qobject_cast<DiagramView *>(m_tab->widget(tab_id)))
@@ -323,7 +323,7 @@ void ProjectDBModel::setIdentifier(const QString &identifier) {
/**
@brief ProjectDBModel::folioBuilt
The folio of a table made while it was being built (QET_LAZY_FOLIOS)
The folio of a table made while it was being built (lazy folios)
is built: read the database, as opening does once it has filled it.
Nothing for any other model.
*/
@@ -391,7 +391,7 @@ void ProjectDBModel::fillValue()
{
m_record.clear();
//Opening builds a table before the database is filled, and fills
//it after: a table on a folio built late (QET_LAZY_FOLIOS) does
//it after: a table on a folio built late (lazy folios) does
//the same, so that it is laid out as it would have been on
//opening -- empty until its folio is built (folioBuilt())
if (m_fill_when_built) {
@@ -566,7 +566,7 @@ void QetGraphicsTableItem::initLink()
if (!m_pending_previous_table_uuid.isNull())
{
//The built folios only: a previous table on a folio not built
//yet (QET_LAZY_FOLIOS) is linked when that folio is
//yet (lazy folios) is linked when that folio is
QETProject *project = this->diagram()->project();
ElementProvider provider_(project->builtFolios());
auto previous_table = provider_.tableFromUuid(m_pending_previous_table_uuid);
@@ -583,7 +583,7 @@ void QetGraphicsTableItem::initLink()
/**
@brief QetGraphicsTableItem::previousTableUuid
@return the uuid of the table before this one in its chain, linked or
still waiting for its folio to be built (QET_LAZY_FOLIOS); null if none
still waiting for its folio to be built (lazy folios); null if none
*/
QUuid QetGraphicsTableItem::previousTableUuid() const
{
+4 -4
View File
@@ -1116,7 +1116,7 @@ bool Element::fromXml(QDomElement &e,
dc.fromXml(e.firstChildElement(QStringLiteral("elementInformations")),
QStringLiteral("elementInformation"));
//Changed through the project database while its folio was not
//built (QET_LAZY_FOLIOS): the change, not what the file says
//built (lazy folios): the change, not what the file says
if (diagram() && diagram()->project())
if (const auto edited = diagram()->project()->dataBase()->takeUnbuiltEdit(m_uuid))
dc = *edited;
@@ -1255,7 +1255,7 @@ QDomElement Element::toXml(
//if this element is linked to other elements,
//save the uuid of each other elements
//A partner on a folio not built yet (QET_LAZY_FOLIOS), which this
//A partner on a folio not built yet (lazy folios), which this
//symbol will be linked to, is saved too, in the order the symbol was
//saved with: saving needs no partner built (stage D5a)
QList<std::pair<QUuid, int>> links;
@@ -1661,7 +1661,7 @@ void Element::initLink(QETProject *prj)
//The symbols built: on the folios built, and those built alone as
//partners on folios not built (Diagram::buildSymbols()). A partner
//not built yet (QET_LAZY_FOLIOS) is linked when it is, and the
//not built yet (lazy folios) is linked when it is, and the
//saved list is kept until then, for the order it gives
ElementProvider ep(prj->folios());
QList<QUuid> uuids;
@@ -1689,7 +1689,7 @@ void Element::initLink(QETProject *prj)
/**
@brief Element::pendingLinks
@return the uuids of the partners this symbol was saved linked to and
is not linked to yet: those on a folio not built yet (QET_LAZY_FOLIOS),
is not linked to yet: those on a folio not built yet (lazy folios),
until initLink() runs again once it is
*/
QSet<QUuid> Element::pendingLinks() const
+1 -1
View File
@@ -1090,7 +1090,7 @@ QList<Terminal *> relatedPotentialTerminal (
// If terminal parent element is a folio report.
if (all_diagram && terminal -> parentElement() -> linkType() & Element::AllReport)
{
//The report's partner on a folio not built yet (QET_LAZY_FOLIOS)
//The report's partner on a folio not built yet (lazy folios)
//is built, so that a potential is followed as far as when every
//folio is; not while folios are being read or built, which
//would build whole report chains
+26 -15
View File
@@ -327,7 +327,7 @@ void QETProject::init()
connect(&m_titleblocks_collection, &TitleBlockTemplatesCollection::changed, this, &QETProject::updateDiagramsTitleBlockTemplate);
connect(&m_titleblocks_collection, &TitleBlockTemplatesCollection::aboutToRemove, this, &QETProject::removeDiagramsTitleBlockTemplate);
//What changes the saved items of folios not built (QET_LAZY_FOLIOS):
//What changes the saved items of folios not built (lazy folios):
//a folio's position, number or the folio total in their texts,
//the report and cross-reference settings, a symbol's definition.
//A folio not built is then built to be saved (writesKeptFolios())
@@ -469,7 +469,7 @@ QETProject::ProjectState QETProject::openFile(QFile *file)
//folios' parts read when they are built (stage D2);
//any other, or one whose index cannot be used, is read whole
m_opened_from_index = false;
if (QetContainer::isZip(content) && qEnvironmentVariableIntValue("QET_LAZY_FOLIOS") == 1)
if (QetContainer::isZip(content) && lazyFolios())
{
QList<QetZip::Entry> entries;
QString why;
@@ -599,7 +599,7 @@ QList<Diagram *> QETProject::diagrams() const
/**
@brief QETProject::folios
@return the folios of this project, whether their items are built yet
or not (a project opened with QET_LAZY_FOLIOS); see Diagram::isLoaded()
or not (a project opened with lazy folios); see Diagram::isLoaded()
*/
QList<Diagram *> QETProject::folios() const
{
@@ -637,7 +637,7 @@ QList<Diagram *> QETProject::cableLabelFolios()
/**
@brief QETProject::builtFolios
@return the folios of this project whose items are built: all of them,
but for a project opened with QET_LAZY_FOLIOS
but for a project opened with lazy folios
*/
QList<Diagram *> QETProject::builtFolios() const
{
@@ -769,7 +769,7 @@ void QETProject::buildFolios(const QList<Diagram *> &folios) const
/**
@brief QETProject::buildFoliosHolding
Build the folios not built yet (QET_LAZY_FOLIOS) holding a symbol of
Build the folios not built yet (lazy folios) holding a symbol of
one of the kinds @p kinds -- if @p free_only, one which may be linked
to nothing once built: none of the partners it was saved linked to is
in the project. What a search for such symbols must build to find
@@ -836,7 +836,7 @@ void QETProject::buildFoliosHolding(ElementData::Types kinds, bool free_only)
/**
@brief QETProject::buildFoliosHoldingSymbols
Build the folios not built yet (QET_LAZY_FOLIOS) holding one of the
Build the folios not built yet (lazy folios) holding one of the
symbols @p symbols, found in the project database once it holds the
folios not built, else in the XML kept for them: what needs those
symbols while the project is being read, before the database knows
@@ -886,7 +886,7 @@ void QETProject::buildFoliosHoldingSymbols(const QSet<QUuid> &symbols)
/**
@brief QETProject::symbolsOnUnbuiltFolios
@return the uuids of the symbols on the folios not built yet
(QET_LAZY_FOLIOS) that building them places
(lazy folios) that building them places
*/
QSet<QUuid> QETProject::symbolsOnUnbuiltFolios() const
{
@@ -1884,7 +1884,7 @@ std::optional<QUuid> QETProject::elementAutoNumIdToLink(
@brief QETProject::symbolNumbering
@return the numbering of every symbol placed on the folios, read from
the symbol on a folio built and, on a folio not built yet
(QET_LAZY_FOLIOS), from what building it would give: its information
(lazy folios), from what building it would give: its information
in the project database's store, the scheme it would be linked to,
its sequential numbers and its kind as the database has them.
*/
@@ -2342,7 +2342,7 @@ QDomDocument QETProject::toXml(QHash<int, QByteArray> *kept_folios, QStringList
//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
//With @p kept_folios, a folio not built (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
//spliceKeptFolios() -- when building it would write that same
@@ -2786,6 +2786,8 @@ QETResult QETProject::write()
}
else
{
//Folios not built (lazy folios) written as read when that
//is what building them would write (toXml())
QHash<int, QByteArray> kept_folios;
QDomDocument xml_project(toXml(&kept_folios));
if (!QET::writeXmlText(spliceKeptFolios(xml_project.toString(4), kept_folios),
@@ -3030,7 +3032,7 @@ bool QETProject::usesElement(const ElementsLocation &location) const
@brief QETProject::folioXml
@return the built folio @p folio written as saving writes it: its
symbols keep the links to partners on folios not built yet
(QET_LAZY_FOLIOS), which Diagram::toXml() alone leaves out
(lazy folios), which Diagram::toXml() alone leaves out
*/
QDomDocument QETProject::folioXml(Diagram *folio)
{
@@ -3042,7 +3044,7 @@ QDomDocument QETProject::folioXml(Diagram *folio)
/**
@brief QETProject::buildFoliosHoldingTables
Build the folios not built yet (QET_LAZY_FOLIOS) that hold a drawn
Build the folios not built yet (lazy folios) that hold a drawn
table, found from the index the project was opened from when it has
one: what a list of the project's tables needs, and no more
*/
@@ -3063,7 +3065,7 @@ void QETProject::buildFoliosHoldingTables()
/**
@brief QETProject::unbuiltFolioHasTables
@return true if @p folio, not built yet (QET_LAZY_FOLIOS), has a drawn
@return true if @p folio, not built yet (lazy folios), has a drawn
table: from the index it was opened from, else from its XML
*/
bool QETProject::unbuiltFolioHasTables(Diagram *folio) const
@@ -3079,7 +3081,7 @@ bool QETProject::unbuiltFolioHasTables(Diagram *folio) const
/**
@brief QETProject::unbuiltFolioElements
@return the locations of the symbols placed on the folios not built yet
(QET_LAZY_FOLIOS), each once, read from the project database once it
(lazy folios), each once, read from the project database once it
holds those folios, else from the XML kept for them as building them
reads it (Diagram::fromXml())
*/
@@ -3362,11 +3364,11 @@ void QETProject::readProjectXml(QDomDocument &xml_project)
m_data_base.prefillFromDocument(xml_project);
}
//QET_LAZY_FOLIOS leaves the folios to be built when needed only
//Folios are left to be built when needed (lazyFolios()) only
//when the database can be filled from the document: otherwise
//filling it from the folios builds every one of them anyway, late
//and more slowly than reading them now
m_lazy_open = qEnvironmentVariableIntValue("QET_LAZY_FOLIOS") == 1;
m_lazy_open = lazyFolios();
if (m_lazy_open) {
const QString why = projectDataBase::documentRefusal(xml_project);
if (!why.isEmpty()) {
@@ -3489,6 +3491,15 @@ void QETProject::readFoliosFromIndex()
updateDiagramsFolioData();
}
/**
@brief QETProject::lazyFolios
@see the declaration
*/
bool QETProject::lazyFolios()
{
return qEnvironmentVariableIntValue("QET_EAGER_FOLIOS") != 1;
}
/**
@brief QETProject::readFolioPart
@return the folio part @p file of the .qetz this project was opened
+8 -2
View File
@@ -124,7 +124,7 @@ class QETProject : public QObject
ProjectState state() const;
QList<Diagram *> diagrams() const;
//The folios whether their items are built or not
//(QET_LAZY_FOLIOS); diagrams() builds them
//(lazy folios); diagrams() builds them
QList<Diagram *> folios() const;
bool deferringFolios() const {return m_deferring_folios;}
int unloadedFolioCount() const;
@@ -162,6 +162,12 @@ class QETProject : public QObject
/// process can destroy the project before the write finishes (crash).
static void setBackupEnabled(bool enabled);
/// Whether a folio is built only when it is needed, not all on
/// opening (stage D6): yes, unless the
/// environment variable QET_EAGER_FOLIOS=1 asks for every folio
/// built on opening, as QElectroTech did before
static bool lazyFolios();
/// Number of crash-recovery snapshots kept per project, written in
/// turn by writeBackup(), so one bad write cannot replace the only copy
static constexpr int BackupGenerations = 3;
@@ -267,7 +273,7 @@ class QETProject : public QObject
static QString normalizedAutoNumName(const QString &name);
QVector<Element *> elementsUsingElementAutoNum(const QString &title) const;
/// A placed symbol's numbering, whether its folio is built or
/// not (QET_LAZY_FOLIOS): what is asked of every symbol of the
/// not (lazy folios): what is asked of every symbol of the
/// project when one is numbered
struct SymbolNumbering {
const Element *element = nullptr; ///< null on a folio not built
+2 -2
View File
@@ -465,7 +465,7 @@ void QetScriptApi::setLive(QStringList *log)
/**
@brief QetScriptApi::unbuiltInformation
@return the information of the symbol @p elementUuid on the folio
@p folioIndex when that folio is not built (QET_LAZY_FOLIOS) and the
@p folioIndex when that folio is not built (lazy folios) and the
symbol's information can be read and changed through the project
database alone (projectDataBase::canEditUnbuilt()); nothing otherwise,
the folio to be built
@@ -486,7 +486,7 @@ std::optional<DiagramContext> QetScriptApi::unbuiltInformation(int folioIndex, c
/**
@brief QetScriptApi::built
@return @p folio, built if it was not yet (QET_LAZY_FOLIOS), as showing
@return @p folio, built if it was not yet (lazy folios), as showing
it builds it: what a call reading or changing its items needs. A
folio's own data (title block, border, wire defaults) needs no build.
*/
+1 -1
View File
@@ -15,7 +15,7 @@
namespace {
//The folios holding a terminal, built: a folio not built yet
//(QET_LAZY_FOLIOS) holding none is not built for this
//(lazy folios) holding none is not built for this
QList<Diagram *> terminalFolios(QETProject *project)
{
project->buildFoliosHolding(ElementData::Terminal, false);
@@ -58,7 +58,7 @@ class ChangeElementInformationCommand : public QUndoCommand
/**
@brief The ChangeStoredElementInformationCommand class
Change the information of a symbol given by its uuid, built or not
(QET_LAZY_FOLIOS): through the symbol when it is built, through the
(lazy folios): through the symbol when it is built, through the
project database when it is not (projectDataBase::canEditUnbuilt()).
*/
class ChangeStoredElementInformationCommand : public QUndoCommand
+1 -1
View File
@@ -53,7 +53,7 @@ QDomElement WiringListExport::climbToDiagram(QDomNode node) const
/**
The project as the export reads it: its symbol collection and its folios
in order, each with its "order". A folio not built (QET_LAZY_FOLIOS) is
in order, each with its "order". A folio not built (lazy folios) is
not built for it: its XML is copied, and what QElectroTech computes for
its wires' ends -- the labels of the symbols they end on and of their
partners, the terminals' names -- is filled in from the symbols built
+25 -25
View File
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Lazy folios (QET_LAZY_FOLIOS),
// Lazy folios (on by default, QET_EAGER_FOLIOS=1 for every folio built),
// linked against the application's objects: a folio shown in a project
// opened without building its folios draws and links as in the project
// opened as usual, building only it and the folios its links and tables
@@ -59,7 +59,7 @@ static void revisionEveryFolio(const QString &source, const QString &output, con
const QString &path, int label_folio = -1)
{
QString error;
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
QETProject revised(source);
const int unbuilt = revised.unloadedFolioCount();
QetScriptApi api(&revised);
@@ -85,7 +85,7 @@ static void revisionEveryFolio(const QString &source, const QString &output, con
check(built <= with_tables, "saving a new revision builds only the folios holding a table");
else
check(revised.folios().at(label_folio)->isLoaded(), "a folio whose label changed is built to save");
qunsetenv("QET_LAZY_FOLIOS");
qputenv("QET_EAGER_FOLIOS", "1");
const QString usual_path = output + "/" + name + "-usual" + (qetz ? ".qetz" : ".qet");
{
QETProject usual(source);
@@ -99,7 +99,7 @@ static void revisionEveryFolio(const QString &source, const QString &output, con
else { usual.setFilePath(usual_path); check(usual.write().isOk(), "revision saved when built"); }
}
QETProject lazy_back(lazy_path), usual_back(usual_path);
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
//What a save says of itself (file name, path, time) left out
auto lines = [&path](QETProject &project) {
QStringList list = sortedLines(project.toXml().toString(), path);
@@ -364,7 +364,7 @@ int main(int argc, char **argv)
qputenv("QET_LAZY_SAVE_KEPT", "1");
try {
const QString output = QString::fromLocal8Bit(argv[3]);
qunsetenv("QET_LAZY_FOLIOS");
qputenv("QET_EAGER_FOLIOS", "1");
//A file saved by this version: its folios carry their uuids,
//which opening without building them needs
const QString path = output + "/lazy_folios.qet";
@@ -391,9 +391,9 @@ int main(int argc, char **argv)
QETProject eager(path);
check(eager.state() == QETProject::Ok, "project opens");
{
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
QETProject lazy_strips(path);
qunsetenv("QET_LAZY_FOLIOS");
qputenv("QET_EAGER_FOLIOS", "1");
auto strip_of = [](const QETProject &project) {
for (TerminalStrip *strip : project.terminalStrip())
if (strip->name() == QStringLiteral("X99")) return strip->physicalTerminalCount();
@@ -414,7 +414,7 @@ int main(int argc, char **argv)
}
check(linked > 0, "the project has linked symbols");
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
auto same = [&](QETProject &lazy, int i, const char *what) {
Diagram *folio = lazy.folios().at(i);
lazy.buildFolioToShow(folio);
@@ -542,9 +542,9 @@ int main(int argc, char **argv)
}
{
QETProject edited(path), usual(path);
qunsetenv("QET_LAZY_FOLIOS");
qputenv("QET_EAGER_FOLIOS", "1");
QETProject usual_edited(path);
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
edit(edited, busiest);
std::printf("edits on folio %d (%d links to other folios): %d folios not built\n",
busiest + 1, most, edited.unloadedFolioCount());
@@ -624,9 +624,9 @@ int main(int argc, char **argv)
//After everyday edits on a folio: as when built, others not built
{
QETProject edited(path), usual(path);
qunsetenv("QET_LAZY_FOLIOS");
qputenv("QET_EAGER_FOLIOS", "1");
QETProject usual_edited(path);
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
edit(edited, busiest);
edit(usual_edited, busiest);
QFile file(path); file.open(QIODevice::ReadOnly);
@@ -656,9 +656,9 @@ int main(int argc, char **argv)
//links reach are built to be saved, the others not
{
QETProject renamed(path);
qunsetenv("QET_LAZY_FOLIOS");
qputenv("QET_EAGER_FOLIOS", "1");
QETProject usual_renamed(path);
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
for (QETProject *project : {&renamed, &usual_renamed}) {
Diagram *folio = project->folios().at(busiest);
TitleBlockProperties block = folio->border_and_titleblock.exportTitleBlock();
@@ -673,9 +673,9 @@ int main(int argc, char **argv)
//folio is built to be saved
{
QETProject changed(path);
qunsetenv("QET_LAZY_FOLIOS");
qputenv("QET_EAGER_FOLIOS", "1");
QETProject usual_changed(path);
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
for (QETProject *project : {&changed, &usual_changed}) {
DiagramContext properties = project->projectProperties();
properties.addValue(QStringLiteral("lazy_test"), QStringLiteral("1"));
@@ -736,7 +736,7 @@ int main(int argc, char **argv)
check(out.open(QIODevice::WriteOnly), "copy written");
out.write(document.toByteArray(4));
out.close();
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
qputenv("QET_LAZY_FOLIOS_TRACE", "1");
static int built_late; built_late = 0;
const QtMessageHandler previous = qInstallMessageHandler(
@@ -834,9 +834,9 @@ int main(int argc, char **argv)
std::printf(".qetz folio added, moved, removed: %d folios built\n",
unbuilt - shuffled.unloadedFolioCount());
check(shuffled.unloadedFolioCount() == unbuilt, "adding, moving and removing a folio builds no other");
qunsetenv("QET_LAZY_FOLIOS");
qputenv("QET_EAGER_FOLIOS", "1");
QETProject usual_shuffled(zipped);
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
shuffle(usual_shuffled);
check(folioRows(shuffled) == folioRows(usual_shuffled), "folios' rows after a move as when built");
}
@@ -923,7 +923,7 @@ int main(int argc, char **argv)
check(changed.writeContainerFile(changed_path, &error), "saved after the change");
std::printf(".qetz symbol on folio %d changed by a script: %d folios built, %d by saving\n",
folio_index + 1, 0, unbuilt - changed.unloadedFolioCount());
qunsetenv("QET_LAZY_FOLIOS");
qputenv("QET_EAGER_FOLIOS", "1");
const QString usual_path = output + "/changed-usual.qetz";
{
QETProject usual_changed(zipped);
@@ -932,7 +932,7 @@ int main(int argc, char **argv)
check(usual_changed.writeContainerFile(usual_path, &error), "saved after the change when built");
}
QETProject changed_back(changed_path), usual_back(usual_path);
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
check(sortedLines(changed_back.toXml().toString(), path) == sortedLines(usual_back.toXml().toString(), path),
"a symbol changed through the database saved as when built");
check(QetScriptApi(&changed_back).elementInfo(folio_index, uuid, "comment") == value, "the change saved");
@@ -989,9 +989,9 @@ int main(int argc, char **argv)
std::printf(".qetz saved untouched: %d of %d folios not built before, %d after\n",
unbuilt, int(folios.size()), untouched.unloadedFolioCount());
check(untouched.unloadedFolioCount() > 0, "saving an untouched .qetz does not build every folio");
qunsetenv("QET_LAZY_FOLIOS");
qputenv("QET_EAGER_FOLIOS", "1");
QETProject kept_back(kept_path);
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
check(kept_back.toXml().toString() == eager.toXml().toString(),
"a .qetz saved without building holds the project");
@@ -1006,14 +1006,14 @@ int main(int argc, char **argv)
//read back too: what a save and a reading do to a project is
//not what is checked here
const QString usual_path = output + "/edited-usual.qetz";
qunsetenv("QET_LAZY_FOLIOS");
qputenv("QET_EAGER_FOLIOS", "1");
{
QETProject edited_usual(path);
edit(edited_usual, busiest);
check(edited_usual.writeContainerFile(usual_path, &error), "edits saved with every folio built");
}
QETProject edited_back(edited_path), usual_back(usual_path);
qputenv("QET_LAZY_FOLIOS", "1");
qunsetenv("QET_EAGER_FOLIOS");
check(sortedLines(edited_back.toXml().toString(), path) == sortedLines(usual_back.toXml().toString(), path),
"an edited .qetz saved without building holds what the edits made");
//Each symbol's links as saved, partners on folios not built
+1 -1
View File
@@ -328,7 +328,7 @@ private slots:
env.insert(QStringLiteral("QET_ENABLE_SCRIPTING"), QStringLiteral("1"));
env.insert(QStringLiteral("QET_CHECK_ELEMENT_INFO_STORE"), QStringLiteral("1"));
if (eager) {
env.remove(QStringLiteral("QET_LAZY_FOLIOS")); //every folio built on opening
env.insert(QStringLiteral("QET_EAGER_FOLIOS"), QStringLiteral("1")); //every folio built on opening
}
env.insert(QStringLiteral("HOME"), home);
env.insert(QStringLiteral("XDG_CONFIG_HOME"), home + QStringLiteral("/config"));