diff --git a/sources/borderproperties.cpp b/sources/borderproperties.cpp index b1812032c..b9ab708bd 100644 --- a/sources/borderproperties.cpp +++ b/sources/borderproperties.cpp @@ -117,9 +117,15 @@ void BorderProperties::toXml(QDomElement &e) const */ void BorderProperties::fromXml(QDomElement &e) { if (e.hasAttribute("cols")) columns_count = e.attribute("cols").toInt(); - if (e.hasAttribute("colsize")) columns_width = e.attribute("colsize").toInt(); if (e.hasAttribute("rows")) rows_count = e.attribute("rows").toInt(); - if (e.hasAttribute("rowsize")) rows_height = e.attribute("rowsize").toInt(); + // The sizes are decimals (toXml() writes them with %1), read as + // BorderTitleBlock::borderFromXml() does; an unreadable value is + // left as it was. + bool ok; + qreal size = e.attribute("colsize").toDouble(&ok); + if (ok && qIsFinite(size)) columns_width = size; + size = e.attribute("rowsize").toDouble(&ok); + if (ok && qIsFinite(size)) rows_height = size; if (e.hasAttribute("displaycols")) display_columns = e.attribute("displaycols") == "true"; if (e.hasAttribute("displayrows")) display_rows = e.attribute("displayrows") == "true"; } diff --git a/tests/qttest/CMakeLists.txt b/tests/qttest/CMakeLists.txt index 1af0799b1..48dede22d 100644 --- a/tests/qttest/CMakeLists.txt +++ b/tests/qttest/CMakeLists.txt @@ -1001,6 +1001,16 @@ add_test(NAME tst_xrefpos COMMAND tst_xrefpos) target_include_directories(tst_xrefpos PRIVATE ${QET_DIR}/sources) target_link_libraries(tst_xrefpos PRIVATE Qt::Test Qt::Widgets Qt::Xml pugixml::pugixml) +# BorderProperties::fromXml() -- the project's for new folios: +# column width and row height are decimals and are read as such. +add_executable( + tst_borderpropertiesxml + tst_borderpropertiesxml.cpp + ${QET_DIR}/sources/borderproperties.cpp) +add_test(NAME tst_borderpropertiesxml COMMAND tst_borderpropertiesxml) +target_include_directories(tst_borderpropertiesxml PRIVATE ${QET_DIR}/sources) +target_link_libraries(tst_borderpropertiesxml PRIVATE Qt::Test Qt::Xml) + # Qt 6.4.2 writes the attributes of an element in an order that changes from # one process to the next, so a project saved twice by two runs of the binary # differs in bytes only (seen on projects without any numbering, too). A fixed diff --git a/tests/qttest/tst_borderpropertiesxml.cpp b/tests/qttest/tst_borderpropertiesxml.cpp new file mode 100644 index 000000000..c5aedc7c1 --- /dev/null +++ b/tests/qttest/tst_borderpropertiesxml.cpp @@ -0,0 +1,119 @@ +/* + Copyright 2006-2026 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "borderproperties.h" + +#include +#include + +/** + BorderProperties::fromXml() -- the element a project keeps for + its new folios. Its column width and row height are decimals, written + by toXml() as "%1"; they used to be read with toInt(), which is 0 for + "60.5", and 0 is then clamped to the 5 px minimum by the folio. +*/ +class tst_borderpropertiesxml : public QObject +{ + Q_OBJECT + + static QDomElement border(const QString &attributes) + { + static QDomDocument doc; + doc.setContent(QStringLiteral("").arg(attributes)); + return doc.documentElement(); + } + + static BorderProperties base() + { + BorderProperties p; + p.columns_count = 17; + p.columns_width = 60; + p.rows_count = 8; + p.rows_height = 80; + p.display_columns = true; + p.display_rows = true; + return p; + } + +private slots: + void sizesAreReadAsDecimals_data() + { + QTest::addColumn("colsize"); + QTest::addColumn("rowsize"); + QTest::addColumn("width"); + QTest::addColumn("height"); + QTest::newRow("whole numbers") << "50" << "100" << 50.0 << 100.0; + QTest::newRow("decimals") << "60.5" << "80.25" << 60.5 << 80.25; + QTest::newRow("rounds down") << "61.3" << "61.3" << 61.3 << 61.3; + QTest::newRow("rounds up") << "61.7" << "61.7" << 61.7 << 61.7; + } + + void sizesAreReadAsDecimals() + { + QFETCH(QString, colsize); + QFETCH(QString, rowsize); + QFETCH(qreal, width); + QFETCH(qreal, height); + + BorderProperties p = base(); + QDomElement e = border(QStringLiteral("cols=\"17\" colsize=\"%1\" rows=\"8\" rowsize=\"%2\"") + .arg(colsize, rowsize)); + p.fromXml(e); + QCOMPARE(p.columns_width, width); + QCOMPARE(p.rows_height, height); + QCOMPARE(p.columns_count, 17); + QCOMPARE(p.rows_count, 8); + } + + void savedSizesComeBack() + { + BorderProperties saved = base(); + saved.columns_width = 60.5; + saved.rows_height = 80.25; + QDomDocument doc; + QDomElement e = doc.createElement(QStringLiteral("border")); + saved.toXml(e); + + BorderProperties loaded = base(); + loaded.fromXml(e); + QCOMPARE(loaded.columns_width, 60.5); + QCOMPARE(loaded.rows_height, 80.25); + } + + // An unreadable size leaves the previous value, as a missing one does. + void unreadableSizeIsLeftAlone_data() + { + QTest::addColumn("attributes"); + QTest::newRow("missing") << "cols=\"17\" rows=\"8\""; + QTest::newRow("text") << "colsize=\"wide\" rowsize=\"tall\""; + QTest::newRow("nan") << "colsize=\"nan\" rowsize=\"nan\""; + QTest::newRow("inf") << "colsize=\"inf\" rowsize=\"-inf\""; + } + + void unreadableSizeIsLeftAlone() + { + QFETCH(QString, attributes); + BorderProperties p = base(); + QDomElement e = border(attributes); + p.fromXml(e); + QCOMPARE(p.columns_width, 60.0); + QCOMPARE(p.rows_height, 80.0); + } +}; + +QTEST_GUILESS_MAIN(tst_borderpropertiesxml) +#include "tst_borderpropertiesxml.moc"