diff --git a/sources/diagram.cpp b/sources/diagram.cpp index 271e0713f..3c673c86c 100644 --- a/sources/diagram.cpp +++ b/sources/diagram.cpp @@ -45,13 +45,24 @@ #include namespace { - /// Format a position as a string that sorts the same way the numbers do - /// (fixed precision, so "-" and decimals compare correctly as text). + /// Format a coordinate as a string that sorts the same way the number + /// does. Plain fixed-precision formatting ("%.4f") does NOT do this -- + /// e.g. "15.0000" sorts before "5.0000" as text even though 15 > 5 -- + /// so shift into a non-negative range and zero-pad to a fixed width + /// before comparing. + QString coordinateKey(double v) + { + //Diagram coordinates are nowhere near this range; the offset and + //width just need to be big enough that shifted values are always + //non-negative and always the same digit count. + constexpr double offset = 1e9; + qint64 scaled = qint64(qRound64((v + offset) * 10000.0)); + return QStringLiteral("%1").arg(scaled, 20, 10, QLatin1Char('0')); + } + QString positionKey(const QPointF &pos) { - return QStringLiteral("%1|%2") - .arg(pos.x(), 0, 'f', 4) - .arg(pos.y(), 0, 'f', 4); + return coordinateKey(pos.x()) + QLatin1Char('|') + coordinateKey(pos.y()); } /// Sort key for Diagram::toXml()'s block: the element's own