diff --git a/sources/conductornumexport.cpp b/sources/conductornumexport.cpp index f969a2015..f44e5b1bf 100644 --- a/sources/conductornumexport.cpp +++ b/sources/conductornumexport.cpp @@ -19,11 +19,12 @@ #include "qetproject.h" #include "qetapp.h" #include "diagram.h" -#include "diagramcontent.h" #include "qetgraphicsitem/conductor.h" #include "qetgraphicsitem/conductortextitem.h" #include "qetgraphicsitem/element.h" #include "qetgraphicsitem/terminal.h" +#include "dataBase/projectdatabase.h" +#include "properties/elementdata.h" #include @@ -114,10 +115,30 @@ void ConductorNumExport::fillHash() { //We used this rx to avoid insert num composed only withe white space. QRegularExpression rx("^ *$"); - for (Diagram *d : m_project->diagrams()) + 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 + //project database, by the same rules + QList unbuilt; + for (Diagram *d : m_project->folios()) + if (!d->isLoaded()) unbuilt << d->uuid(); + for (const auto &wire : m_project->dataBase()->wiresOnFolios(unbuilt)) { - DiagramContent dc(d, false); - for (Conductor *c : dc.conductors()) + if (wire.text.isEmpty() || wire.text.contains(rx)) { + continue; + } + const bool report1 = ElementData::typeFromString(wire.kind1) & ElementData::AllReport; + const bool report2 = ElementData::typeFromString(wire.kind2) & ElementData::AllReport; + if (!(report1 && report2)) { + count(wire.text); + } + } + for (Diagram *d : m_project->builtFolios()) + { + //Its wires only: a DiagramContent would follow their + //potentials onto other folios, building those not built + for (Conductor *c : d->conductors()) { QString num = c->textItem()->toPlainText(); if (num.isEmpty() || num.contains(rx)) { diff --git a/sources/dataBase/projectdatabase.cpp b/sources/dataBase/projectdatabase.cpp index 007bad900..460e68b29 100644 --- a/sources/dataBase/projectdatabase.cpp +++ b/sources/dataBase/projectdatabase.cpp @@ -1263,6 +1263,32 @@ QList projectDataBase::symbolsOnFolios(const QList return symbols; } +/** + @brief projectDataBase::wiresOnFolios + @return the wires on the folios @p folios, folio by folio in that order, + read from the conductor table as it is (see elementTypesOnFolios()) +*/ +QList projectDataBase::wiresOnFolios(const QList &folios) const +{ + QList wires; + QSqlQuery query(m_data_base); + query.prepare(QStringLiteral("SELECT c.text, e1.type, e2.type FROM conductor c " + "LEFT JOIN element e1 ON e1.uuid = c.terminal1_element_uuid " + "LEFT JOIN element e2 ON e2.uuid = c.terminal2_element_uuid " + "WHERE c.diagram_uuid = :folio ORDER BY c.rowid")); + for (const QUuid &folio : folios) { + query.bindValue(QStringLiteral(":folio"), folio.toString()); + if (!query.exec()) { + continue; + } + while (query.next()) { + wires.append({query.value(0).toString(), query.value(1).toString(), + query.value(2).toString()}); + } + } + return wires; +} + /** @brief projectDataBase::linkedSymbols @return the symbols @p element is linked to, read from the link table diff --git a/sources/dataBase/projectdatabase.h b/sources/dataBase/projectdatabase.h index 489880ecb..c8583a4cc 100644 --- a/sources/dataBase/projectdatabase.h +++ b/sources/dataBase/projectdatabase.h @@ -191,6 +191,10 @@ class projectDataBase : public QObject }; QList symbolsOnFolios(const QList &folios) const; QList linkedSymbols(const QUuid &element) const; + /// A wire placed on a folio: its text and the kinds of the + /// symbols at its ends (ElementData::typeToString()) + struct FolioWire { QString text; QString kind1; QString kind2; }; + QList wiresOnFolios(const QList &folios) const; static QVariant sequenceValue(const autonum::sequentialNumbers &sequence); static autonum::sequentialNumbers sequenceFromValue(const QVariant &value); diff --git a/sources/ui/terminalnumberingdialog.cpp b/sources/ui/terminalnumberingdialog.cpp index 6e30d32cc..2e180a2f5 100644 --- a/sources/ui/terminalnumberingdialog.cpp +++ b/sources/ui/terminalnumberingdialog.cpp @@ -13,6 +13,16 @@ #include #include +namespace { + //The folios holding a terminal, built: a folio not built yet + //(QET_LAZY_FOLIOS) holding none is not built for this +QList terminalFolios(QETProject *project) +{ + project->buildFoliosHolding(ElementData::Terminal, false); + return project->builtFolios(); +} +} + /** * @brief TerminalNumberingDialog::TerminalNumberingDialog * Constructor @@ -31,7 +41,7 @@ TerminalNumberingDialog::TerminalNumberingDialog(QWidget *parent, QETProject *pr // Collect all unique terminal strip prefixes from the project if (project) { QSet prefixes; - foreach (Diagram *diagram, project->diagrams()) { + foreach (Diagram *diagram, terminalFolios(project)) { foreach (QGraphicsItem *qgi, diagram->items()) { if (Element *elmt = qgraphicsitem_cast(qgi)) { if (elmt->elementData().m_type == ElementData::Terminal) { @@ -153,7 +163,7 @@ QUndoCommand* TerminalNumberingDialog::getUndoCommand(QETProject *project) const QList termList; // 2. Collect all terminals from all folios in the project - foreach (Diagram *diagram, project->diagrams()) { + foreach (Diagram *diagram, terminalFolios(project)) { int fIndex = diagram->folioIndex(); foreach (QGraphicsItem *qgi, diagram->items()) { if (Element *elmt = qgraphicsitem_cast(qgi)) { diff --git a/sources/wiringlistexport.cpp b/sources/wiringlistexport.cpp index c56b6fc76..39282ac69 100644 --- a/sources/wiringlistexport.cpp +++ b/sources/wiringlistexport.cpp @@ -28,8 +28,8 @@ QString WiringListExport::findDiagramFolio(const QDomElement &diagramElem) const // The folio number as the folio shows it ("3/12"). The saved "folio" // attribute is its template ("%id/%total"). const int index = diagramElem.attribute("order").toInt(); - if (m_project && index >= 1 && index <= m_project->diagrams().size()) { - return m_project->diagrams().at(index - 1)->border_and_titleblock + if (m_project && index >= 1 && index <= m_project->folios().size()) { + return m_project->folios().at(index - 1)->border_and_titleblock .titleblockInformation().value("folio").toString(); } if (diagramElem.hasAttribute("folio")) return diagramElem.attribute("folio"); diff --git a/tests/qttest/lazy_folios_probe.cpp b/tests/qttest/lazy_folios_probe.cpp index 2947e6b37..2a809693c 100644 --- a/tests/qttest/lazy_folios_probe.cpp +++ b/tests/qttest/lazy_folios_probe.cpp @@ -29,6 +29,9 @@ #include "../../sources/TerminalStrip/terminalstrip.h" #include "../../sources/ui/elementpropertieswidget.h" #include "../../sources/conductorautonumerotation.h" +#include "../../sources/conductornumexport.h" +#include "../../sources/wiringlistexport.h" +#include "../../sources/ui/terminalnumberingdialog.h" #include "../../sources/diagramcontent.h" #include "../../sources/diagramview.h" #include "../../sources/diagramevent/diagrameventaddpaste.h" @@ -376,6 +379,15 @@ int main(int argc, char **argv) for (const QString &title : titles) check(gaps(numbered, title) == gaps(eager, title), "a scheme's gaps as when built"); check(numbered.unloadedFolioCount() == folios.size() - strip_folios.size(), "numbering read without building"); + { + //Wire numbers exported from the database filled from the + //document, as when built (D5) + QETProject exported(path); + check(ConductorNumExport(&exported).wiresNum() == ConductorNumExport(&eager).wiresNum(), + "wire numbers of a .qet exported as when built"); + check(exported.unloadedFolioCount() == folios.size() - strip_folios.size(), + "exporting a .qet's wire numbers builds no folio"); + } //A symbol placed on a folio, numbered by a scheme others follow QString location, title; int folio = -1; @@ -695,6 +707,13 @@ int main(int argc, char **argv) ++continued; } check(continued > 0, "a folio whose table continues another"); + { + //The wiring list export writes the whole project out + //(toXml()), building every folio: as when built + QETProject exported(zipped); + check(WiringListExport(&exported).toCsvString() == WiringListExport(&eager).toCsvString(), + "wiring list exported as when built"); + } //Numbering, the searches for symbols and the unused symbols //are answered from the database: no folio file is read @@ -780,6 +799,26 @@ int main(int argc, char **argv) check(listed.unloadedFolioCount() > 0, "listing the tables does not build every folio"); } + //The wire numbers export and the terminal + //numbering dialog: as when built, building only the folios + //holding a terminal (D5) + { + QETProject exported(zipped); + const int unbuilt = exported.unloadedFolioCount(); + check(ConductorNumExport(&exported).wiresNum() == ConductorNumExport(&eager).wiresNum(), + "wire numbers exported as when built"); + check(exported.unloadedFolioCount() == unbuilt, "exporting wire numbers builds no folio"); + { TerminalNumberingDialog dialog(nullptr, &exported); } + int with_terminals = 0; + for (Diagram *folio : folios) + for (Element *element : folio->elements()) + if (element->elementData().m_type == ElementData::Terminal) { ++with_terminals; break; } + std::printf(".qetz terminal numbering: %d folios built, %d hold a terminal\n", + unbuilt - exported.unloadedFolioCount(), with_terminals); + check(exported.folios().size() - exported.unloadedFolioCount() <= with_terminals + (folios.size() - unbuilt), + "terminal numbering builds only the folios holding a terminal"); + } + //Saved as a .qetz without building the folios not touched //(D4): their parts and rows copied as they were QETProject untouched(zipped);