From 7c4355338b9d35a5eb653a0bfc8d649f85347489 Mon Sep 17 00:00:00 2001 From: ispyisail Date: Sun, 27 Sep 2026 21:28:36 +1300 Subject: [PATCH] Fix DXF export writing entities in a different order every time Exporting the same folio to DXF twice gave files with the same entities in a different order, so two exports never compared equal and a DXF could not be diffed to spot a change. The export walked diagram->items(), whose order follows memory addresses; saving had the same fault until bugtracker #343. Items are now taken in stacking order (z, then insertion order, which a load makes the file's order), from the same rect query Diagram::toXml() uses. Anything the query misses keeps its items() place after the rest. Checked in the Export dialog on grafcet.qet, three folios, two exports per build: master's differ every time, these are byte-identical, and both contain exactly the same entities, only reordered. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01G2d2Zi8BfrYRPX88zhaoFG --- sources/exportdialog.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/sources/exportdialog.cpp b/sources/exportdialog.cpp index 6eeaabfc3..19a3b7f20 100644 --- a/sources/exportdialog.cpp +++ b/sources/exportdialog.cpp @@ -37,6 +37,7 @@ #include "qetmessagebox.h" #include +#include #include #include #include @@ -483,7 +484,24 @@ void ExportDialog::generateDxf( // QList list_terminals; // Determine les elements a "XMLiser" - foreach(QGraphicsItem *qgi, diagram -> items()) { + // In stacking order (z, then insertion order, which a load makes the + // file's order), not items() order: that follows memory addresses, so + // the same folio came out in a different order on every export, as + // saving did before bugtracker #343. A rect query gives stacking order + // even with NoIndex; anything it misses keeps its items() place after + // the rest. + QList stacked_items = diagram -> items( + QRectF(-1e9, -1e9, 2e9, 2e9), Qt::IntersectsItemBoundingRect, + Qt::AscendingOrder); + { + const QSet ranked(stacked_items.cbegin(), stacked_items.cend()); + for (QGraphicsItem *qgi : diagram -> items()) { + if (!ranked.contains(qgi)) { + stacked_items << qgi; + } + } + } + for (QGraphicsItem *qgi : std::as_const(stacked_items)) { if (Element *elmt = qgraphicsitem_cast(qgi)) { list_elements << elmt; } else if (Conductor *f = qgraphicsitem_cast(qgi)) {