From 2e35afd6e0573ed9c8b79c5ccaea23a5e29a1f51 Mon Sep 17 00:00:00 2001 From: Ladislav Michl Date: Fri, 9 May 2025 00:00:41 +0200 Subject: [PATCH 1/4] Base: sort returned Unit schema description Return schemas name and description vectors sorted by number, so index can be used later to select particular schema. Fixes: 1155f0d75281 ("Base: simplify UnitsSchemas management") --- src/Base/UnitsSchemas.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Base/UnitsSchemas.cpp b/src/Base/UnitsSchemas.cpp index f79e1d4317..f5418e712c 100644 --- a/src/Base/UnitsSchemas.cpp +++ b/src/Base/UnitsSchemas.cpp @@ -53,7 +53,11 @@ size_t UnitsSchemas::count() const std::vector UnitsSchemas::getVec(const std::function& fn) { std::vector vec; - std::transform(pack.specs.begin(), pack.specs.end(), std::back_inserter(vec), fn); + auto specs = pack.specs; + std::sort(specs.begin(), specs.end(), [](const UnitsSchemaSpec& a, const UnitsSchemaSpec& b) { + return a.num < b.num; + }); + std::transform(specs.begin(), specs.end(), std::back_inserter(vec), fn); return vec; } From e577bebe56e25cea1a13180caf71a823db8cdb29 Mon Sep 17 00:00:00 2001 From: Ladislav Michl Date: Tue, 6 May 2025 23:32:27 +0200 Subject: [PATCH 2/4] Base: fix Python interface for Unit schema selection Fixes: 1155f0d75281 ("Base: simplify UnitsSchemas management") --- src/Base/UnitsApiPy.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Base/UnitsApiPy.cpp b/src/Base/UnitsApiPy.cpp index f6a0d49870..7efd122c2d 100644 --- a/src/Base/UnitsApiPy.cpp +++ b/src/Base/UnitsApiPy.cpp @@ -135,7 +135,7 @@ PyObject* UnitsApi::sGetSchema(PyObject* /*self*/, PyObject* args) return nullptr; } - return Py_BuildValue("i", count()); + return Py_BuildValue("i", schemas->currentSchema()->getNum()); } PyObject* UnitsApi::sSetSchema(PyObject* /*self*/, PyObject* args) @@ -164,7 +164,7 @@ PyObject* UnitsApi::sSchemaTranslate(PyObject* /*self*/, PyObject* args) if (index < 0 || index >= static_cast(count())) { PyErr_SetString(PyExc_ValueError, - std::string {"invalid schema index:" + std::to_string(index)}.c_str()); + std::string {"invalid schema index: " + std::to_string(index)}.c_str()); return nullptr; } @@ -172,7 +172,8 @@ PyObject* UnitsApi::sSchemaTranslate(PyObject* /*self*/, PyObject* args) double factor {}; std::string unitStr; - const std::string unitStrLocalised = schemaTranslate(quant, factor, unitStr); + auto schema = std::make_unique(schemas->spec(index)); + const std::string unitStrLocalised = schema->translate(quant, factor, unitStr); Py::Tuple res {3}; res[0] = Py::String {unitStrLocalised, "utf-8"}; From 67d0345870b759a4da40c8e4871629a96735a34f Mon Sep 17 00:00:00 2001 From: Syres916 <46537884+Syres916@users.noreply.github.com> Date: Fri, 9 May 2025 15:47:40 +0100 Subject: [PATCH 3/4] Base: fix default unit schema Fix the transcription error which occured while moving into single structure. Default schema now uses milimeters again. Fixes: 1155f0d75281 ("Base: simplify UnitsSchemas management") --- src/Base/UnitsSchemasData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Base/UnitsSchemasData.h b/src/Base/UnitsSchemasData.h index 0c8ab3ca87..d50e1c6b75 100644 --- a/src/Base/UnitsSchemasData.h +++ b/src/Base/UnitsSchemasData.h @@ -82,7 +82,7 @@ inline const UnitsSchemaSpec s2 }; inline const UnitsSchemaSpec s3 -{ 0, "Internal", "m", false, false, QT_TRANSLATE_NOOP("UnitsApi", "Internal (m, m², m³)"), true, +{ 0, "Internal", "mm", false, false, QT_TRANSLATE_NOOP("UnitsApi", "Standard (mm, kg, s, °)"), true, { { "Length", { { 1e-6 , "mm" , 1.0 }, From 602880ed806503b16eac7f00a11a733fb514a729 Mon Sep 17 00:00:00 2001 From: Ladislav Michl Date: Wed, 14 May 2025 10:24:02 +0200 Subject: [PATCH 4/4] Base: revert to using ASCII chararacters for imperial lengths The new unit schema management is using U+2032 and U+2033 characters for feet and inches while parser is expecting only ' and ", while U+2032 and U+2033 are used for arcminute and arcsecond. While this is not an ideal solution and parser should deal with both, revert back to ASCII for now. Fixes: 1155f0d75281 ("Base: simplify UnitsSchemas management") --- src/Base/UnitsSchema.cpp | 13 +++++++------ src/Base/UnitsSchemasData.h | 12 ++++++------ tests/src/Base/SchemaTests.cpp | 18 ++++++++++-------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/Base/UnitsSchema.cpp b/src/Base/UnitsSchema.cpp index c576d65919..68662e8971 100644 --- a/src/Base/UnitsSchema.cpp +++ b/src/Base/UnitsSchema.cpp @@ -103,12 +103,13 @@ UnitsSchema::toLocale(const Quantity& quant, const double factor, const std::str std::string valueString = Lc.toString((quant.getValue() / factor), format.toFormat(), format.precision).toStdString(); - return fmt::format( - "{}{}{}", - valueString, - unitString.empty() || unitString == "°" || unitString == "″" || unitString == "′" ? "" - : " ", - unitString); + return fmt::format("{}{}{}", + valueString, + unitString.empty() || unitString == "°" || unitString == "″" + || unitString == "′" || unitString == "\"" || unitString == "'" + ? "" + : " ", + unitString); } bool UnitsSchema::isMultiUnitLength() const diff --git a/src/Base/UnitsSchemasData.h b/src/Base/UnitsSchemasData.h index d50e1c6b75..c37260f3ab 100644 --- a/src/Base/UnitsSchemasData.h +++ b/src/Base/UnitsSchemasData.h @@ -581,8 +581,8 @@ inline const UnitsSchemaSpec s7 { "Length", { { 0.00000254 , "in" , 25.4 }, { 2.54 , "thou" , 0.0254 }, - { 304.8 , "″" , 25.4 }, - { 914.4 , "′" , 304.8 }, + { 304.8 , "\"" , 25.4 }, + { 914.4 , "'" , 304.8 }, { 1'609'344.0 , "yd" , 914.4 }, { 1'609'344'000.0 , "mi" , 1'609'344.0 }, { 0 , "in" , 25.4 }} @@ -649,7 +649,7 @@ inline std::size_t greatestCommonDenominator(const std::size_t a, const std::siz } /** - * double -> [feet′][inches[-fraction]″], e.g.: 3′4-1/4″ + * double -> [feet'][inches[-fraction]"], e.g.: 3'4-1/4" */ inline std::string toFractional(const double value) { @@ -676,19 +676,19 @@ inline std::string toFractional(const double value) if (inches > 0) { resultParts.push_back(fmt::format("{}", inches)); if (numerator == 0) { - resultParts.emplace_back("″"); + resultParts.emplace_back("\""); } } if (numerator > 0) { if (inches > 0) { resultParts.emplace_back("-"); } - resultParts.push_back(fmt::format("{}/{}″", numerator, denominator)); + resultParts.push_back(fmt::format("{}/{}\"", numerator, denominator)); } return fmt::format("{}{}{}", value < 0 ? "-" : "", - feet > 0 ? fmt::format("{}′", feet) : "", + feet > 0 ? fmt::format("{}'", feet) : "", fmt::join(resultParts, "")); } diff --git a/tests/src/Base/SchemaTests.cpp b/tests/src/Base/SchemaTests.cpp index 8cfc3644c3..59aa242054 100644 --- a/tests/src/Base/SchemaTests.cpp +++ b/tests/src/Base/SchemaTests.cpp @@ -21,6 +21,7 @@ #include #include "Base/Exception.h" +#include "Base/Tools.h" #include "Base/Unit.h" #include "Base/Quantity.h" #include "Base/UnitsApi.h" @@ -33,6 +34,7 @@ using Base::Quantity; using Base::QuantityFormat; using Base::RuntimeError; +using Base::Tools; using Base::Unit; using Base::UnitsApi; using Base::UnitsSchema; @@ -263,7 +265,7 @@ TEST_F(SchemaTest, imperial_safe_user_str_same) { constexpr auto val {304.8}; const auto result = set("Imperial", Unit::Length, val); - const auto expect {"1.00′"}; + const auto expect = Tools::escapeQuotesFromString("1.00'"); EXPECT_EQ(result, expect); } @@ -272,7 +274,7 @@ TEST_F(SchemaTest, imperial_safe_user_str_more) { constexpr auto val {310.0}; const auto result = set("Imperial", Unit::Length, val); - const auto expect {"1.02′"}; + const auto expect = Tools::escapeQuotesFromString("1.02'"); EXPECT_EQ(result, expect); } @@ -281,7 +283,7 @@ TEST_F(SchemaTest, imperial_safe_user_str_less) { constexpr auto val {300.0}; const auto result = set("Imperial", Unit::Length, val); - const auto expect {"11.81″"}; + const auto expect = Tools::escapeQuotesFromString("11.81\""); EXPECT_EQ(result, expect); } @@ -290,7 +292,7 @@ TEST_F(SchemaTest, imperial_safe_user_str_one_inch) { constexpr auto val {25.4}; const auto result = set("Imperial", Unit::Length, val); - const auto expect {"1.00″"}; + const auto expect = Tools::escapeQuotesFromString("1.00\""); EXPECT_EQ(result, expect); } @@ -299,7 +301,7 @@ TEST_F(SchemaTest, imperial_building_special_function_length_inch) { constexpr auto val {25.4}; const auto result = set("ImperialBuilding", Unit::Length, val); - const auto expect {"1″"}; + const auto expect = Tools::escapeQuotesFromString("1\""); EXPECT_EQ(result, expect); } @@ -308,7 +310,7 @@ TEST_F(SchemaTest, imperial_building_special_function_length_foot) { constexpr auto val {25.4 * 12}; const auto result = set("ImperialBuilding", Unit::Length, val); - const auto expect {"1′"}; + const auto expect = Tools::escapeQuotesFromString("1'"); EXPECT_EQ(result, expect); } @@ -317,7 +319,7 @@ TEST_F(SchemaTest, imperial_building_special_function_length) { constexpr auto val {360.6}; const auto result = set("ImperialBuilding", Unit::Length, val); - const auto expect {"1′2-1/4″"}; + const auto expect = Tools::escapeQuotesFromString("1'2-1/4\""); EXPECT_EQ(result, expect); } @@ -326,7 +328,7 @@ TEST_F(SchemaTest, imperial_building_special_function_length_neg) { constexpr auto val {-360.6}; const auto result = set("ImperialBuilding", Unit::Length, val); - const auto expect {"-1′2-1/4″"}; + const auto expect = Tools::escapeQuotesFromString("-1'2-1/4\""); EXPECT_EQ(result, expect); }