From 5c4fa8fadfa138639d6518231cc16eb605813ff5 Mon Sep 17 00:00:00 2001 From: ispyisail Date: Mon, 12 Oct 2026 19:27:22 +1300 Subject: [PATCH] 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 --- sources/TerminalStrip/terminalstrip.cpp | 2 +- sources/cli_export.cpp | 6 +-- sources/conductornumexport.cpp | 2 +- sources/dataBase/projectdatabase.cpp | 22 ++++---- sources/dataBase/projectdatabase.h | 4 +- sources/diagram.cpp | 10 ++-- sources/diagram.h | 2 +- sources/diagramcontent.h | 2 +- sources/diagramview.cpp | 2 +- sources/elementprovider.cpp | 4 +- sources/elementprovider.h | 2 +- sources/projectview.cpp | 2 +- .../ViewItem/projectdbmodel.cpp | 4 +- .../ViewItem/qetgraphicstableitem.cpp | 4 +- sources/qetgraphicsitem/element.cpp | 8 +-- sources/qetgraphicsitem/terminal.cpp | 2 +- sources/qetproject.cpp | 41 +++++++++------ sources/qetproject.h | 10 +++- sources/scripting/qetscriptapi.cpp | 4 +- sources/ui/terminalnumberingdialog.cpp | 2 +- .../changeelementinformationcommand.h | 2 +- sources/wiringlistexport.cpp | 2 +- tests/qttest/lazy_folios_probe.cpp | 50 +++++++++---------- tests/qttest/tst_resaveunchanged.cpp | 2 +- 24 files changed, 104 insertions(+), 87 deletions(-) diff --git a/sources/TerminalStrip/terminalstrip.cpp b/sources/TerminalStrip/terminalstrip.cpp index cbb537cdb..5bbcf5cee 100644 --- a/sources/TerminalStrip/terminalstrip.cpp +++ b/sources/TerminalStrip/terminalstrip.cpp @@ -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 terminals; diff --git a/sources/cli_export.cpp b/sources/cli_export.cpp index cdb00096f..8214d4eea 100644 --- a/sources/cli_export.cpp +++ b/sources/cli_export.cpp @@ -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 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 kept_folios; const QDomDocument doc = project.toXml(&kept_folios); QFile file(output); diff --git a/sources/conductornumexport.cpp b/sources/conductornumexport.cpp index f44e5b1bf..ea43be511 100644 --- a/sources/conductornumexport.cpp +++ b/sources/conductornumexport.cpp @@ -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 unbuilt; for (Diagram *d : m_project->folios()) diff --git a/sources/dataBase/projectdatabase.cpp b/sources/dataBase/projectdatabase.cpp index b076e92a0..15da3aeae 100644 --- a/sources/dataBase/projectdatabase.cpp +++ b/sources/dataBase/projectdatabase.cpp @@ -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 diagrams = m_project->folios(); if (diagram_nodes.size() != diagrams.size()) { @@ -1215,7 +1215,7 @@ QSet 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 projectDataBase::folioUuidsOfElements(const QSet &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()) { diff --git a/sources/dataBase/projectdatabase.h b/sources/dataBase/projectdatabase.h index 3448346ac..8d95fe0c5 100644 --- a/sources/dataBase/projectdatabase.h +++ b/sources/dataBase/projectdatabase.h @@ -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 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); diff --git a/sources/diagram.cpp b/sources/diagram.cpp index 316593e78..c47406143 100644 --- a/sources/diagram.cpp +++ b/sources/diagram.cpp @@ -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 > 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. diff --git a/sources/diagram.h b/sources/diagram.h index 4117bd8e6..5785b7efd 100644 --- a/sources/diagram.h +++ b/sources/diagram.h @@ -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 diff --git a/sources/diagramcontent.h b/sources/diagramcontent.h index 0afcf4516..a693cfdf1 100644 --- a/sources/diagramcontent.h +++ b/sources/diagramcontent.h @@ -108,7 +108,7 @@ class DiagramContent QList 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> m_potential_conductors; }; QDebug &operator<<(QDebug, DiagramContent &); diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp index 5a1bc6590..7ece3ee4a 100644 --- a/sources/diagramview.cpp +++ b/sources/diagramview.cpp @@ -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() { diff --git a/sources/elementprovider.cpp b/sources/elementprovider.cpp index 174151811..3bb4c4165 100644 --- a/sources/elementprovider.cpp +++ b/sources/elementprovider.cpp @@ -55,7 +55,7 @@ ElementProvider::ElementProvider(const QList &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 ElementProvider::folios(ElementData::Types kinds, bool free_only) const @@ -98,7 +98,7 @@ QVector > ElementProvider::freeElement(ElementData::Types filt QList elmt_list; const QList 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 waiting = m_project ? m_project->symbolsOnUnbuiltFolios() : QSet(); diff --git a/sources/elementprovider.h b/sources/elementprovider.h index 5f839c38c..592088d83 100644 --- a/sources/elementprovider.h +++ b/sources/elementprovider.h @@ -55,7 +55,7 @@ class ElementProvider QList 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; diff --git a/sources/projectview.cpp b/sources/projectview.cpp index ab62a3591..158cc2ae5 100644 --- a/sources/projectview.cpp +++ b/sources/projectview.cpp @@ -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(m_tab->widget(tab_id))) diff --git a/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp b/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp index cf9525cc2..eb76c5662 100644 --- a/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp +++ b/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp @@ -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) { diff --git a/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.cpp b/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.cpp index 0b6922ebf..6fe42bfcd 100644 --- a/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.cpp +++ b/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.cpp @@ -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 { diff --git a/sources/qetgraphicsitem/element.cpp b/sources/qetgraphicsitem/element.cpp index 87fc394b5..03e600436 100644 --- a/sources/qetgraphicsitem/element.cpp +++ b/sources/qetgraphicsitem/element.cpp @@ -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> 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 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 Element::pendingLinks() const diff --git a/sources/qetgraphicsitem/terminal.cpp b/sources/qetgraphicsitem/terminal.cpp index 5cade6949..b232d252d 100644 --- a/sources/qetgraphicsitem/terminal.cpp +++ b/sources/qetgraphicsitem/terminal.cpp @@ -1090,7 +1090,7 @@ QList 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 diff --git a/sources/qetproject.cpp b/sources/qetproject.cpp index 3a640c798..1bf67e8a9 100644 --- a/sources/qetproject.cpp +++ b/sources/qetproject.cpp @@ -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 entries; QString why; @@ -599,7 +599,7 @@ QList 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 QETProject::folios() const { @@ -637,7 +637,7 @@ QList 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 QETProject::builtFolios() const { @@ -769,7 +769,7 @@ void QETProject::buildFolios(const QList &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 &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 QETProject::symbolsOnUnbuiltFolios() const { @@ -1884,7 +1884,7 @@ std::optional 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 *kept_folios, QStringList //folio not built is written as , 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 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 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 diff --git a/sources/qetproject.h b/sources/qetproject.h index 8d8d8bded..cd8f12335 100644 --- a/sources/qetproject.h +++ b/sources/qetproject.h @@ -124,7 +124,7 @@ class QETProject : public QObject ProjectState state() const; QList diagrams() const; //The folios whether their items are built or not - //(QET_LAZY_FOLIOS); diagrams() builds them + //(lazy folios); diagrams() builds them QList 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 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 diff --git a/sources/scripting/qetscriptapi.cpp b/sources/scripting/qetscriptapi.cpp index 32247aed9..3f372bdfb 100644 --- a/sources/scripting/qetscriptapi.cpp +++ b/sources/scripting/qetscriptapi.cpp @@ -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 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. */ diff --git a/sources/ui/terminalnumberingdialog.cpp b/sources/ui/terminalnumberingdialog.cpp index 2e180a2f5..89811db79 100644 --- a/sources/ui/terminalnumberingdialog.cpp +++ b/sources/ui/terminalnumberingdialog.cpp @@ -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 terminalFolios(QETProject *project) { project->buildFoliosHolding(ElementData::Terminal, false); diff --git a/sources/undocommand/changeelementinformationcommand.h b/sources/undocommand/changeelementinformationcommand.h index 1d7d2cf70..9f6bcee24 100644 --- a/sources/undocommand/changeelementinformationcommand.h +++ b/sources/undocommand/changeelementinformationcommand.h @@ -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 diff --git a/sources/wiringlistexport.cpp b/sources/wiringlistexport.cpp index c69df19f8..8de281782 100644 --- a/sources/wiringlistexport.cpp +++ b/sources/wiringlistexport.cpp @@ -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 diff --git a/tests/qttest/lazy_folios_probe.cpp b/tests/qttest/lazy_folios_probe.cpp index 3389782b8..09630399c 100644 --- a/tests/qttest/lazy_folios_probe.cpp +++ b/tests/qttest/lazy_folios_probe.cpp @@ -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 diff --git a/tests/qttest/tst_resaveunchanged.cpp b/tests/qttest/tst_resaveunchanged.cpp index c7d7bc409..9cceb2b50 100644 --- a/tests/qttest/tst_resaveunchanged.cpp +++ b/tests/qttest/tst_resaveunchanged.cpp @@ -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"));