From 9e8be1aa23d76e3dcedc562bd0101226ec7bc15f Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 17 Sep 2018 12:38:46 +0200 Subject: [PATCH] extend QuantityFormat to set denominator independent of user settings --- src/App/Application.cpp | 4 +-- src/Base/Quantity.cpp | 1 + src/Base/Quantity.h | 15 ++++++--- src/Base/QuantityPy.xml | 2 +- src/Base/QuantityPyImp.cpp | 53 ++++++++++++++++++++----------- src/Base/UnitsSchemaImperial1.cpp | 2 +- src/Gui/DlgSettingsUnitsImp.cpp | 4 +-- 7 files changed, 53 insertions(+), 28 deletions(-) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 2ad1285524..a412db90c4 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -1577,8 +1577,8 @@ void Application::initApplication(void) UnitsApi::setDecimals(hGrp->GetInt("Decimals", Base::UnitsApi::getDecimals())); // In case we are using fractional inches, get user setting for min unit - int denom = hGrp->GetInt("FracInch", Base::QuantityFormat::getDenominator()); - Base::QuantityFormat::setDenominator(denom); + int denom = hGrp->GetInt("FracInch", Base::QuantityFormat::getDefaultDenominator()); + Base::QuantityFormat::setDefaultDenominator(denom); #if defined (_DEBUG) diff --git a/src/Base/Quantity.cpp b/src/Base/Quantity.cpp index 890c4575ae..fcf38db0ac 100644 --- a/src/Base/Quantity.cpp +++ b/src/Base/Quantity.cpp @@ -52,6 +52,7 @@ QuantityFormat::QuantityFormat() : option(static_cast(OmitGroupSeparator | RejectGroupSeparator)) , format(Fixed) , precision(UnitsApi::getDecimals()) + , denominator(defaultDenominator) { } diff --git a/src/Base/Quantity.h b/src/Base/Quantity.h index 32d1ca2df4..c27b355345 100644 --- a/src/Base/Quantity.h +++ b/src/Base/Quantity.h @@ -36,7 +36,7 @@ namespace Base { -struct QuantityFormat { +struct BaseExport QuantityFormat { enum NumberOption { None = 0x00, OmitGroupSeparator = 0x01, @@ -51,20 +51,27 @@ struct QuantityFormat { NumberOption option; NumberFormat format; int precision; + int denominator; // Default denominator of minimum fractional inch. Only used in certain // schemas. static int defaultDenominator; // i.e 8 for 1/8" - static inline int getDenominator() { + static inline int getDefaultDenominator() { return defaultDenominator; } - static inline void setDenominator(int denom) - { + static inline void setDefaultDenominator(int denom) { defaultDenominator = denom; } + inline int getDenominator() const { + return denominator; + } + + inline void setDenominator(int denom) { + denominator = denom; + } QuantityFormat(); inline char toFormat() const { switch (format) { diff --git a/src/Base/QuantityPy.xml b/src/Base/QuantityPy.xml index b23c9c049c..328c354899 100644 --- a/src/Base/QuantityPy.xml +++ b/src/Base/QuantityPy.xml @@ -70,7 +70,7 @@ Quantity(string) -- arbitrary mixture of numbers and chars defining a Quantity Format of the Quantity - + diff --git a/src/Base/QuantityPyImp.cpp b/src/Base/QuantityPyImp.cpp index 46fdfc6596..b8962f7793 100644 --- a/src/Base/QuantityPyImp.cpp +++ b/src/Base/QuantityPyImp.cpp @@ -607,36 +607,53 @@ Py::String QuantityPy::getUserString(void) const return Py::String(getQuantityPtr()->getUserString().toUtf8(),"utf-8"); } -Py::Tuple QuantityPy::getFormat(void) const +Py::Dict QuantityPy::getFormat(void) const { QuantityFormat fmt = getQuantityPtr()->getFormat(); - Py::Tuple tuple(2); - tuple.setItem(0, Py::Int (fmt.precision)); - tuple.setItem(1, Py::Char(fmt.toFormat())); - return tuple; + Py::Dict dict; + dict.setItem("Precision", Py::Int (fmt.precision)); + dict.setItem("NumberFormat", Py::Char(fmt.toFormat())); + dict.setItem("Denominator", Py::Int(fmt.denominator)); + return dict; } -void QuantityPy::setFormat(Py::Tuple arg) +void QuantityPy::setFormat(Py::Dict arg) { - QuantityFormat fmt; + QuantityFormat fmt = getQuantityPtr()->getFormat(); - Py::Int prec(arg.getItem(0)); - Py::Char form(arg.getItem(1)); - fmt.precision = static_cast(prec); + if (arg.hasKey("Precision")) { + Py::Int prec(arg.getItem("Precision")); + fmt.precision = static_cast(prec); + } + if (arg.hasKey("NumberFormat")) { + Py::Char form(arg.getItem("NumberFormat")); #if PY_MAJOR_VERSION >= 3 - std::string fmtstr = static_cast(Py::String(form)); + std::string fmtstr = static_cast(Py::String(form)); #else - std::string fmtstr = static_cast(form); + std::string fmtstr = static_cast(form); #endif - if (fmtstr.size() != 1) - throw Py::ValueError("Invalid format character"); + if (fmtstr.size() != 1) + throw Py::ValueError("Invalid format character"); - bool ok; - fmt.format = Base::QuantityFormat::toFormat(fmtstr[0], &ok); - if (!ok) - throw Py::ValueError("Invalid format character"); + bool ok; + fmt.format = Base::QuantityFormat::toFormat(fmtstr[0], &ok); + if (!ok) + throw Py::ValueError("Invalid format character"); + } + + if (arg.hasKey("Denominator")) { + Py::Int denom(arg.getItem("Denominator")); + int fracInch = static_cast(denom); + // check that the value is positive and a power of 2 + if (fracInch <= 0) + throw Py::ValueError("Denominator must be higher than zero"); + // bitwise check + if (fracInch & (fracInch - 1)) + throw Py::ValueError("Denominator must be a power of two"); + fmt.denominator = fracInch; + } getQuantityPtr()->setFormat(fmt); } diff --git a/src/Base/UnitsSchemaImperial1.cpp b/src/Base/UnitsSchemaImperial1.cpp index d0a5bead2a..c987d315ad 100644 --- a/src/Base/UnitsSchemaImperial1.cpp +++ b/src/Base/UnitsSchemaImperial1.cpp @@ -230,7 +230,7 @@ QString UnitsSchemaImperialBuilding::schemaTranslate(const Quantity &quant, doub int tmp; // temporary variable for GCD // Get the current user specified minimum denominator - minden = Base::QuantityFormat::getDenominator(); + minden = quant.getFormat().getDenominator(); // Compute and round the total number of fractional units ntot = (int)std::round(totalInches * (double)minden); diff --git a/src/Gui/DlgSettingsUnitsImp.cpp b/src/Gui/DlgSettingsUnitsImp.cpp index 5f3350ab60..ba12c0e451 100644 --- a/src/Gui/DlgSettingsUnitsImp.cpp +++ b/src/Gui/DlgSettingsUnitsImp.cpp @@ -115,7 +115,7 @@ void DlgSettingsUnitsImp::saveSettings() hGrp->SetInt("FracInch", FracInch); // Set the actual format value - Base::QuantityFormat::setDenominator(FracInch); + Base::QuantityFormat::setDefaultDenominator(FracInch); } void DlgSettingsUnitsImp::loadSettings() @@ -129,7 +129,7 @@ void DlgSettingsUnitsImp::loadSettings() ui->spinBoxDecimals->setValue(hGrp->GetInt("Decimals",Base::UnitsApi::getDecimals())); // Get the current user setting for the minimum fractional inch - FracInch = hGrp->GetInt("FracInch", Base::QuantityFormat::getDenominator()); + FracInch = hGrp->GetInt("FracInch", Base::QuantityFormat::getDefaultDenominator()); // Convert fractional inch to the corresponding combobox index using this // handy little equation.