From fcbea2dafdbf80edba2899559eed8b5431ce98dc Mon Sep 17 00:00:00 2001 From: ispyisail Date: Sat, 12 Sep 2026 23:31:26 +1200 Subject: [PATCH] Write model header roles in a stable order Fourth and last instance of the ordering defect, and the inner half of the one fixed in the previous commit. ProjectDBModel::toXml() builds each section's role list from m_header_data.value(key).keys(), and m_header_data is a QHash> -- so both levels are randomised per process. Sorting the sections left the roles inside each section still arriving shuffled, which showed up as children with the same section="0" swapping places between two saves. With this, save idempotence across the shipped examples goes from 6 of 23 to 22 of 24. The two that remain fail for unrelated reasons, not for ordering: schema_indus.qet stores no uuid attribute on its elements at all, so fromXml() invents a fresh one on every load; and affuteuse_250h.qet loses a title block logo's storage attribute and renames a title block template on save. Both are separate defects. Co-Authored-By: Claude Opus 5 --- sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp b/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp index abfe1bf01..1fe814b6a 100644 --- a/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp +++ b/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp @@ -17,6 +17,8 @@ */ #include "projectdbmodel.h" +#include + #include "../../dataBase/projectdatabase.h" #include "../../qetapp.h" #include "../../qetinformation.h" @@ -266,7 +268,13 @@ QDomElement ProjectDBModel::toXml(QDomDocument &document) const //We save all data except the display role, because he was generated in the fly auto list = m_header_data.value(key).keys(); list.removeAll(Qt::DisplayRole); - + //Sorted: m_header_data's inner container is a QHash too, so its + //key order is randomised per process. modelHeaderDataToXml() + //writes the roles of a section in the order given here, so an + //unsorted list reordered the children of that section on + //every save and kept the save irreproducible. + std::sort(list.begin(), list.end()); + horizontal_.insert(key, list); }