Merge pull request #1184 from ispyisail/fix/wiring-list-folio-arrows

Fix the wiring list export dropping wires at folio reports
This commit is contained in:
ispyisail
2026-10-01 09:11:33 +13:00
committed by GitHub
5 changed files with 1056 additions and 62 deletions
+58 -62
View File
@@ -1,5 +1,6 @@
#include "wiringlistexport.h"
#include "qetproject.h"
#include "diagram.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QTextStream>
@@ -24,6 +25,13 @@ QString WiringListExport::normalizeUuid(const QString &u) const
QString WiringListExport::findDiagramFolio(const QDomElement &diagramElem) const
{
if (diagramElem.isNull()) return "";
// 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
.titleblockInformation().value("folio").toString();
}
if (diagramElem.hasAttribute("folio")) return diagramElem.attribute("folio");
if (diagramElem.hasAttribute("title")) return diagramElem.attribute("title");
return "";
@@ -140,6 +148,7 @@ QList<ConductorData> WiringListExport::collectConductors(const QDomElement &root
QDomElement diag = climbToDiagram(cond);
data.folio = findDiagramFolio(diag);
data.folio_index = diag.attribute("order").toInt();
if (data.folio.isEmpty()) data.folio = cond.attribute("folio", cond.attribute("page", ""));
conductors.append(data);
@@ -227,7 +236,10 @@ QString WiringListExport::toCsvString() const
QList<ConductorData> conductors = collectConductors(doc.documentElement());
QList<ConductorData> uniqueConductors;
QMap<QString, ConductorData> partialWires;
// Conductors with one end on a folio report, by that report. All of them
// are collected before any is merged, so the result does not depend on
// the order the folios are saved in.
QMap<QString, QList<ConductorData>> partialWires;
auto normalizePartial = [](ConductorData c, const QString &ph_uuid) {
if (c.el1_uuid == ph_uuid) {
@@ -277,40 +289,50 @@ QString WiringListExport::toCsvString() const
}
QString ph_uuid = el1_ph ? c.el1_uuid : c.el2_uuid;
ConductorData normC = normalizePartial(c, ph_uuid);
QString matching_ph_uuid;
if (!elementsInfo[ph_uuid].links.isEmpty()) {
matching_ph_uuid = elementsInfo[ph_uuid].links.first();
}
if (!matching_ph_uuid.isEmpty() && partialWires.contains(matching_ph_uuid)) {
ConductorData otherHalf = partialWires.take(matching_ph_uuid);
ConductorData merged;
merged.folio = mergeField(otherHalf.folio, normC.folio);
merged.el1_uuid = otherHalf.el1_uuid;
merged.element1_label = otherHalf.element1_label;
merged.terminalname1 = otherHalf.terminalname1;
merged.el2_uuid = normC.el1_uuid;
merged.element2_label = normC.element1_label;
merged.terminalname2 = normC.terminalname1;
merged.tension_protocol = mergeField(otherHalf.tension_protocol, normC.tension_protocol);
merged.conductor_color = mergeField(otherHalf.conductor_color, normC.conductor_color);
merged.conductor_section = mergeField(otherHalf.conductor_section, normC.conductor_section);
merged.function = mergeField(otherHalf.function, normC.function);
uniqueConductors.append(merged);
} else {
partialWires.insert(ph_uuid, normC);
}
partialWires[ph_uuid].append(normalizePartial(c, ph_uuid));
}
for (const ConductorData &leftover : partialWires.values()) {
uniqueConductors.append(leftover);
// Two halves are one wire only when each report of a linked pair carries
// exactly one conductor. With several on a side, the diagram does not say
// which terminal is wired to which, so each conductor gets its own row,
// ending at the report.
QSet<QString> written;
for (auto it = partialWires.cbegin(); it != partialWires.cend(); ++it) {
const QString &ph_uuid = it.key();
if (written.contains(ph_uuid)) continue;
written.insert(ph_uuid);
const QStringList links = elementsInfo.value(ph_uuid).links;
const QString matching_ph_uuid = links.isEmpty() ? QString() : links.first();
const QList<ConductorData> others = partialWires.value(matching_ph_uuid);
if (it.value().size() != 1 || others.size() != 1 || written.contains(matching_ph_uuid)) {
uniqueConductors.append(it.value());
continue;
}
written.insert(matching_ph_uuid);
const ConductorData &otherHalf = it.value().first();
const ConductorData &normC = others.first();
ConductorData merged;
merged.folio = mergeField(otherHalf.folio, normC.folio);
merged.folio_index = std::min(otherHalf.folio_index, normC.folio_index);
merged.el1_uuid = otherHalf.el1_uuid;
merged.element1_label = otherHalf.element1_label;
merged.terminalname1 = otherHalf.terminalname1;
merged.el2_uuid = normC.el1_uuid;
merged.element2_label = normC.element1_label;
merged.terminalname2 = normC.terminalname1;
merged.tension_protocol = mergeField(otherHalf.tension_protocol, normC.tension_protocol);
merged.conductor_color = mergeField(otherHalf.conductor_color, normC.conductor_color);
merged.conductor_section = mergeField(otherHalf.conductor_section, normC.conductor_section);
merged.function = mergeField(otherHalf.function, normC.function);
uniqueConductors.append(merged);
}
for (ConductorData &c : uniqueConductors) {
@@ -322,35 +344,9 @@ QString WiringListExport::toCsvString() const
}
std::sort(uniqueConductors.begin(), uniqueConductors.end(), [](const ConductorData &a, const ConductorData &b) {
QStringList partsA = a.folio.split(',');
QStringList partsB = b.folio.split(',');
int minLen = std::min(partsA.size(), partsB.size());
int folioCmp = 0;
for (int i = 0; i < minLen; ++i) {
bool okA, okB;
int numA = partsA[i].trimmed().toInt(&okA);
int numB = partsB[i].trimmed().toInt(&okB);
if (okA && okB) {
if (numA != numB) {
folioCmp = (numA < numB) ? -1 : 1;
break;
}
} else {
int strCmp = partsA[i].trimmed().compare(partsB[i].trimmed(), Qt::CaseInsensitive);
if (strCmp != 0) {
folioCmp = strCmp;
break;
}
}
}
if (folioCmp == 0 && partsA.size() != partsB.size()) {
folioCmp = (partsA.size() < partsB.size()) ? -1 : 1;
}
if (folioCmp != 0) return folioCmp < 0;
// By the folio's position in the project: its number is free text
// ("3/12", "A-2") and does not sort.
if (a.folio_index != b.folio_index) return a.folio_index < b.folio_index;
int el1Cmp = a.element1_label.toLower().compare(b.element1_label.toLower());
if (el1Cmp != 0) return el1Cmp < 0;
+1
View File
@@ -33,6 +33,7 @@ struct ConductorData {
QString conductor_section;
QString function;
QString folio;
int folio_index = 0; // position of the folio in the project, from 1
};
/**