Merge pull request #20540 from 3x380V/cleanup-schemas-management
Simplify UnitsSchemas management
This commit is contained in:
@@ -27,6 +27,7 @@ Test module for FreeCAD material cards and APIs
|
||||
import unittest
|
||||
import FreeCAD
|
||||
import Materials
|
||||
import sys
|
||||
|
||||
parseQuantity = FreeCAD.Units.parseQuantity
|
||||
|
||||
@@ -37,6 +38,15 @@ class MaterialTestCases(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
""" Setup function to initialize test data """
|
||||
# The test for ThermalExpansionCoefficient causes problems with some localizations
|
||||
# due to the Unicode mu ('\u03bc') character in the units. This will happen with
|
||||
# locales that don't support UTF8 such as zh_CN (It does support UTF-8)
|
||||
try:
|
||||
sys.stdout.reconfigure(errors='replace')
|
||||
except:
|
||||
# reconfigure appeared in 3.7, hope for the best...
|
||||
pass
|
||||
|
||||
self.ModelManager = Materials.ModelManager()
|
||||
self.MaterialManager = Materials.MaterialManager()
|
||||
self.uuids = Materials.UUIDs()
|
||||
@@ -145,12 +155,6 @@ class MaterialTestCases(unittest.TestCase):
|
||||
self.assertIn("SpecularColor", properties)
|
||||
self.assertIn("Transparency", properties)
|
||||
|
||||
#
|
||||
# The test for ThermalExpansionCoefficient causes problems with some localizations
|
||||
# due to the Unicode mu character in the units. This will happen with
|
||||
# locales that don't support UTF8 such as zh_CN (It does support UTF-8)
|
||||
#
|
||||
# When this is a problem simply comment the lines printing ThermalExpansionCoefficient
|
||||
print("Density " + properties["Density"])
|
||||
# print("BulkModulus " + properties["BulkModulus"])
|
||||
print("PoissonRatio " + properties["PoissonRatio"])
|
||||
|
||||
@@ -2100,100 +2100,77 @@ void EditModeConstraintCoinManager::rebuildConstraintNodes(
|
||||
|
||||
QString EditModeConstraintCoinManager::getPresentationString(const Constraint* constraint)
|
||||
{
|
||||
std::string nameStr; // name parameter string
|
||||
QString valueStr; // dimensional value string
|
||||
std::string unitStr; // the actual unit string
|
||||
std::string baseUnitStr; // the expected base unit string
|
||||
double factor; // unit scaling factor, currently not used
|
||||
Base::UnitSystem unitSys; // current unit system
|
||||
|
||||
if (!constraint->isActive) {
|
||||
return QStringLiteral(" ");
|
||||
}
|
||||
|
||||
// Get the current name parameter string of the constraint
|
||||
nameStr = constraint->Name;
|
||||
/**
|
||||
* Hide units if
|
||||
* - user has requested it,
|
||||
* - is being displayed in the base units, -and-
|
||||
* - the schema being used has a clear base unit in the first place.
|
||||
*
|
||||
* Remove unit string if expected unit string matches actual unit string
|
||||
* Example code from: Mod/TechDraw/App/DrawViewDimension.cpp:372
|
||||
*
|
||||
* Hide the default length unit
|
||||
*/
|
||||
auto fixValueStr = [&](const QString& valueStr, const auto& unitStr) -> std::optional<QString> {
|
||||
if (!constraintParameters.bHideUnits || constraint->Type == Sketcher::Angle) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto baseUnitStr {Base::UnitsApi::getBasicLengthUnit()};
|
||||
if (baseUnitStr.empty() || baseUnitStr != unitStr) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// trailing space or non-dig
|
||||
const QRegularExpression rxUnits {QString::fromUtf8(" \\D*$")};
|
||||
auto vStr = valueStr;
|
||||
vStr.remove(rxUnits);
|
||||
return {vStr};
|
||||
};
|
||||
|
||||
// Get the current value string including units
|
||||
valueStr =
|
||||
QString::fromStdString(constraint->getPresentationValue().getUserString(factor, unitStr));
|
||||
double factor {};
|
||||
std::string unitStr; // the actual unit string
|
||||
const auto constrPresValue {constraint->getPresentationValue().getUserString(factor, unitStr)};
|
||||
auto valueStr = QString::fromStdString(constrPresValue);
|
||||
|
||||
// Hide units if user has requested it, is being displayed in the base
|
||||
// units, and the schema being used has a clear base unit in the first
|
||||
// place. Otherwise, display units.
|
||||
if (constraintParameters.bHideUnits && constraint->Type != Sketcher::Angle) {
|
||||
// Only hide the default length unit. Right now there is not an easy way
|
||||
// to get that from the Unit system so we have to manually add it here.
|
||||
// Hopefully this can be added in the future so this code won't have to
|
||||
// be updated if a new units schema is added.
|
||||
unitSys = Base::UnitsApi::getSchema();
|
||||
|
||||
// If this is a supported unit system then define what the base unit is.
|
||||
switch (unitSys) {
|
||||
case Base::UnitSystem::SI1:
|
||||
case Base::UnitSystem::MmMin:
|
||||
baseUnitStr = "mm";
|
||||
break;
|
||||
|
||||
case Base::UnitSystem::SI2:
|
||||
baseUnitStr = "m";
|
||||
break;
|
||||
|
||||
case Base::UnitSystem::ImperialDecimal:
|
||||
baseUnitStr = "in";
|
||||
break;
|
||||
|
||||
case Base::UnitSystem::Centimeters:
|
||||
baseUnitStr = "cm";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Nothing to do
|
||||
break;
|
||||
}
|
||||
|
||||
if (!baseUnitStr.empty()) {
|
||||
// expected unit string matches actual unit string. remove.
|
||||
if (baseUnitStr.compare(unitStr) == 0) {
|
||||
// Example code from: Mod/TechDraw/App/DrawViewDimension.cpp:372
|
||||
QRegularExpression rxUnits(
|
||||
QStringLiteral(" \\D*$")); // space + any non digits at end of string
|
||||
valueStr.remove(rxUnits); // getUserString(defaultDecimals) without units
|
||||
}
|
||||
}
|
||||
auto fixedValueStr = fixValueStr(valueStr, unitStr).value_or(valueStr);
|
||||
switch (constraint->Type) {
|
||||
case Sketcher::Diameter:
|
||||
fixedValueStr.prepend(QChar(0x2300));
|
||||
break;
|
||||
case Sketcher::Radius:
|
||||
fixedValueStr.prepend(QLatin1Char('R'));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (constraint->Type == Sketcher::Diameter) {
|
||||
valueStr.prepend(QChar(216)); // Diameter sign
|
||||
}
|
||||
else if (constraint->Type == Sketcher::Radius) {
|
||||
valueStr.prepend(QChar(82)); // Capital letter R
|
||||
if (!constraintParameters.bShowDimensionalName || constraint->Name.empty()) {
|
||||
return fixedValueStr;
|
||||
}
|
||||
|
||||
/**
|
||||
Create the representation string from the user defined format string
|
||||
Format options are:
|
||||
%N - the constraint name parameter
|
||||
%V - the value of the dimensional constraint, including any unit characters
|
||||
*/
|
||||
if (constraintParameters.bShowDimensionalName && !nameStr.empty()) {
|
||||
QString presentationStr;
|
||||
if (constraintParameters.sDimensionalStringFormat.contains(QLatin1String("%V"))
|
||||
|| constraintParameters.sDimensionalStringFormat.contains(QLatin1String("%N"))) {
|
||||
presentationStr = constraintParameters.sDimensionalStringFormat;
|
||||
presentationStr.replace(QLatin1String("%N"), QString::fromStdString(nameStr));
|
||||
presentationStr.replace(QLatin1String("%V"), valueStr);
|
||||
}
|
||||
else {
|
||||
// user defined format string does not contain any valid parameter, using default format
|
||||
// "%N = %V"
|
||||
presentationStr = QString::fromStdString(nameStr) + QStringLiteral(" = ") + valueStr;
|
||||
}
|
||||
* Create the representation string from the user defined format string
|
||||
* Format options are:
|
||||
* %N - the constraint name parameter
|
||||
* %V - the value of the dimensional constraint, including any unit characters
|
||||
*/
|
||||
auto sDimFmt {constraintParameters.sDimensionalStringFormat};
|
||||
if (!sDimFmt.contains(QLatin1String("%V"))
|
||||
&& !sDimFmt.contains(QLatin1String("%N"))) { // using default format "%N = %V"
|
||||
|
||||
return presentationStr;
|
||||
return QString::fromStdString(constraint->Name) + QString::fromLatin1(" = ") + valueStr;
|
||||
}
|
||||
|
||||
return valueStr;
|
||||
sDimFmt.replace(QLatin1String("%N"), QString::fromStdString(constraint->Name));
|
||||
sDimFmt.replace(QLatin1String("%V"), fixedValueStr);
|
||||
|
||||
return sDimFmt;
|
||||
}
|
||||
|
||||
std::set<int> EditModeConstraintCoinManager::detectPreselectionConstr(const SoPickedPoint* Point,
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <QWidget>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include "GeneralSettingsWidget.h"
|
||||
#include <gsl/pointers>
|
||||
#include <App/Application.h>
|
||||
@@ -182,7 +183,7 @@ void GeneralSettingsWidget::onUnitSystemChanged(int index)
|
||||
if (index < 0) {
|
||||
return; // happens when clearing the combo box in retranslateUi()
|
||||
}
|
||||
Base::UnitsApi::setSchema(static_cast<Base::UnitSystem>(index));
|
||||
Base::UnitsApi::setSchema(index);
|
||||
ParameterGrp::handle hGrp =
|
||||
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Units");
|
||||
hGrp->SetInt("UserSchema", index);
|
||||
@@ -213,15 +214,16 @@ void GeneralSettingsWidget::retranslateUi()
|
||||
_unitSystemLabel->setText(createLabelText(tr("Unit System")));
|
||||
|
||||
_unitSystemComboBox->clear();
|
||||
ParameterGrp::handle hGrpUnits =
|
||||
|
||||
auto addItem = [&, index {0}](const std::string& item) mutable {
|
||||
_unitSystemComboBox->addItem(QString::fromStdString(item), index++);
|
||||
};
|
||||
auto descriptions = Base::UnitsApi::getDescriptions();
|
||||
std::for_each(descriptions.begin(), descriptions.end(), addItem);
|
||||
|
||||
const ParameterGrp::handle hGrpUnits =
|
||||
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Units");
|
||||
auto userSchema = hGrpUnits->GetInt("UserSchema", 0);
|
||||
int num = static_cast<int>(Base::UnitSystem::NumUnitSystemTypes);
|
||||
for (int i = 0; i < num; i++) {
|
||||
QString item = Base::UnitsApi::getDescription(static_cast<Base::UnitSystem>(i));
|
||||
_unitSystemComboBox->addItem(item, i);
|
||||
}
|
||||
_unitSystemComboBox->setCurrentIndex(userSchema);
|
||||
_unitSystemComboBox->setCurrentIndex(static_cast<int>(hGrpUnits->GetInt("UserSchema", 0)));
|
||||
|
||||
_navigationStyleLabel->setText(createLabelText(tr("Navigation Style")));
|
||||
_navigationStyleComboBox->clear();
|
||||
|
||||
@@ -39,17 +39,11 @@ using namespace TechDraw;
|
||||
|
||||
bool DimensionFormatter::isMultiValueSchema() const
|
||||
{
|
||||
bool angularMeasure = (m_dimension->Type.isValue("Angle") ||
|
||||
m_dimension->Type.isValue("Angle3Pt"));
|
||||
const bool angularMeasure =
|
||||
(m_dimension->Type.isValue("Angle") || m_dimension->Type.isValue("Angle3Pt"));
|
||||
|
||||
if (Base::UnitsApi::isMultiUnitAngle() &&
|
||||
angularMeasure) {
|
||||
return true;
|
||||
} else if (Base::UnitsApi::isMultiUnitLength() &&
|
||||
!angularMeasure) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return (Base::UnitsApi::isMultiUnitAngle() && angularMeasure)
|
||||
|| (Base::UnitsApi::isMultiUnitLength() && !angularMeasure);
|
||||
}
|
||||
|
||||
std::string DimensionFormatter::formatValue(const qreal value,
|
||||
@@ -57,145 +51,117 @@ std::string DimensionFormatter::formatValue(const qreal value,
|
||||
const Format partial,
|
||||
const bool isDim) const
|
||||
{
|
||||
// Base::Console().Message("DF::formatValue() - %s isRestoring: %d\n",
|
||||
// m_dimension->getNameInDocument(), m_dimension->isRestoring());
|
||||
bool angularMeasure = m_dimension->Type.isValue("Angle") || m_dimension->Type.isValue("Angle3Pt");
|
||||
bool areaMeasure = m_dimension->Type.isValue("Area");
|
||||
QLocale loc;
|
||||
const bool angularMeasure =
|
||||
m_dimension->Type.isValue("Angle") || m_dimension->Type.isValue("Angle3Pt");
|
||||
const bool areaMeasure = m_dimension->Type.isValue("Area");
|
||||
|
||||
Base::Quantity asQuantity;
|
||||
asQuantity.setValue(value);
|
||||
Base::Unit unit;
|
||||
if (angularMeasure) {
|
||||
asQuantity.setUnit(Base::Unit::Angle);
|
||||
unit = Base::Unit::Angle;
|
||||
}
|
||||
else if (areaMeasure) {
|
||||
asQuantity.setUnit(Base::Unit::Area);
|
||||
unit = Base::Unit::Area;
|
||||
}
|
||||
else {
|
||||
asQuantity.setUnit(Base::Unit::Length);
|
||||
unit = Base::Unit::Length;
|
||||
}
|
||||
|
||||
Base::Quantity asQuantity {value, unit};
|
||||
|
||||
QStringList qsl = getPrefixSuffixSpec(qFormatSpec);
|
||||
const std::string formatPrefix = qsl[0].toStdString();
|
||||
const std::string formatSuffix = qsl[1].toStdString();
|
||||
QString formatSpecifier = qsl[2];
|
||||
|
||||
// this handles mm to inch/km/parsec etc and decimal positions but
|
||||
// won't give more than Global_Decimals precision
|
||||
QString qUserString = QString::fromStdString(asQuantity.getUserString());
|
||||
std::string basicString = formatPrefix + asQuantity.getUserString() + formatSuffix;
|
||||
|
||||
//get formatSpec prefix/suffix/specifier
|
||||
QStringList qsl = getPrefixSuffixSpec(qFormatSpec);
|
||||
QString formatPrefix = qsl[0]; //FormatSpec prefix
|
||||
QString formatSuffix = qsl[1]; //FormatSpec suffix
|
||||
QString formatSpecifier = qsl[2]; //FormatSpec specifier
|
||||
|
||||
QString qMultiValueStr;
|
||||
QString qBasicUnit = QString::fromStdString(Base::UnitsApi::getBasicLengthUnit());
|
||||
|
||||
QString formattedValue;
|
||||
if (isMultiValueSchema() && partial == Format::UNALTERED) {
|
||||
//handle multi value schemes (yd/ft/in, dms, etc). don't even try to use Alt Decimals or hide units
|
||||
qMultiValueStr = formatPrefix + qUserString + formatSuffix;
|
||||
return qMultiValueStr.toStdString();
|
||||
} else {
|
||||
//not multivalue schema
|
||||
if (formatSpecifier.isEmpty()) {
|
||||
Base::Console().Warning("Warning - no numeric format in Format Spec %s - %s\n",
|
||||
qPrintable(qFormatSpec), m_dimension->getNameInDocument());
|
||||
return qFormatSpec.toStdString();
|
||||
}
|
||||
return basicString; // Don't even try to use Alt Decimals or hide units
|
||||
}
|
||||
|
||||
// for older TD drawings the formatSpecifier "%g" was used, but the number of decimals was
|
||||
// neverheless limited. To keep old drawings, we limit the number of decimals too
|
||||
// if the TD preferences option to use the global decimal number is set
|
||||
// the formatSpecifier can have a prefix and/or suffix
|
||||
if (m_dimension->useDecimals() && formatSpecifier.contains(QStringLiteral("%g"), Qt::CaseInsensitive)) {
|
||||
int globalPrecision = Base::UnitsApi::getDecimals();
|
||||
// change formatSpecifier to e.g. "%.2f"
|
||||
QString newSpecifier = QString::fromStdString("%." + std::to_string(globalPrecision) + "f");
|
||||
formatSpecifier.replace(QStringLiteral("%g"), newSpecifier, Qt::CaseInsensitive);
|
||||
}
|
||||
if (formatSpecifier.isEmpty()) {
|
||||
Base::Console().Warning("Warning - no numeric format in Format Spec %s - %s\n",
|
||||
qPrintable(qFormatSpec),
|
||||
m_dimension->getNameInDocument());
|
||||
return qFormatSpec.toStdString();
|
||||
}
|
||||
|
||||
// since we are not using a multiValueSchema, we know that angles are in '°' and for
|
||||
// lengths we can get the unit of measure from UnitsApi::getBasicLengthUnit.
|
||||
// for older TD drawings the formatSpecifier "%g" was used, but the number of decimals was
|
||||
// nevertheless limited. To keep old drawings, we limit the number of decimals too
|
||||
// if the TD preferences option to use the global decimal number is set
|
||||
// the formatSpecifier can have a prefix and/or suffix
|
||||
if (m_dimension->useDecimals()
|
||||
&& formatSpecifier.contains(QStringLiteral("%g"), Qt::CaseInsensitive)) {
|
||||
const int globalPrecision = Base::UnitsApi::getDecimals();
|
||||
// change formatSpecifier to e.g. "%.2f"
|
||||
const QString newSpecifier =
|
||||
QString::fromStdString("%." + std::to_string(globalPrecision) + "f");
|
||||
formatSpecifier.replace(QStringLiteral("%g"), newSpecifier, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
// TODO: check the weird schemas (MKS, Imperial1)that report different UoM
|
||||
// for different values
|
||||
// since we are not using a multiValueSchema, we know that angles are in '°' and for
|
||||
// lengths we can get the unit of measure from UnitsApi::getBasicLengthUnit.
|
||||
|
||||
// get value in the base unit with default decimals
|
||||
// for the conversion we use the same method as in DlgUnitsCalculator::valueChanged
|
||||
// get the conversion factor for the unit
|
||||
// the result is now just val / convertValue because val is always in the base unit
|
||||
// don't do this for angular values since they are not in the BaseLengthUnit
|
||||
double userVal;
|
||||
if (angularMeasure) {
|
||||
userVal = asQuantity.getValue();
|
||||
qBasicUnit = QStringLiteral("°");
|
||||
}
|
||||
else {
|
||||
double convertValue = Base::Quantity::parse("1" + qBasicUnit.toStdString()).getValue();
|
||||
userVal = asQuantity.getValue() / convertValue;
|
||||
if (areaMeasure) {
|
||||
userVal = userVal / convertValue; // divide again as area is length²
|
||||
qBasicUnit = qBasicUnit + QStringLiteral("²");
|
||||
}
|
||||
}
|
||||
// TODO: check the weird schemas (MKS, Imperial1) that report different UoM for different values
|
||||
|
||||
if (isTooSmall(userVal, formatSpecifier)) {
|
||||
Base::Console().Warning("Dimension %s value %.6f is too small for format specifier: %s\n",
|
||||
m_dimension->getNameInDocument(), userVal, qPrintable(formatSpecifier));
|
||||
}
|
||||
// get value in the base unit with default decimals
|
||||
// for the conversion we use the same method as in DlgUnitsCalculator::valueChanged
|
||||
// get the conversion factor for the unit
|
||||
// the result is now just val / convertValue because val is always in the base unit
|
||||
// don't do this for angular values since they are not in the BaseLengthUnit
|
||||
std::string qBasicUnit =
|
||||
angularMeasure ? "°" : Base::UnitsApi::getBasicLengthUnit();
|
||||
double userVal = asQuantity.getValue();
|
||||
|
||||
formattedValue = formatValueToSpec(userVal, formatSpecifier);
|
||||
|
||||
// replace decimal sign if necessary
|
||||
QChar dp = QChar::fromLatin1('.');
|
||||
if (loc.decimalPoint() != dp) {
|
||||
formattedValue.replace(dp, loc.decimalPoint());
|
||||
if (!angularMeasure) {
|
||||
const double convertValue = Base::Quantity::parse("1" + qBasicUnit).getValue();
|
||||
userVal /= convertValue;
|
||||
if (areaMeasure) {
|
||||
userVal /= convertValue; // divide again as area is length²
|
||||
qBasicUnit += "²";
|
||||
}
|
||||
}
|
||||
|
||||
//formattedValue is now in formatSpec format with local decimal separator
|
||||
if (isTooSmall(userVal, formatSpecifier)) {
|
||||
Base::Console().Warning("Dimension %s value %.6f is too small for format specifier: %s\n",
|
||||
m_dimension->getNameInDocument(),
|
||||
userVal,
|
||||
qPrintable(formatSpecifier));
|
||||
}
|
||||
|
||||
QString formattedValue = formatValueToSpec(userVal, formatSpecifier);
|
||||
|
||||
// replace decimal sign if necessary
|
||||
constexpr QChar dp = QChar::fromLatin1('.');
|
||||
if (const QLocale loc; loc.decimalPoint() != dp) {
|
||||
formattedValue.replace(dp, loc.decimalPoint());
|
||||
}
|
||||
|
||||
// formattedValue is now in formatSpec format with local decimal separator
|
||||
std::string formattedValueString = formattedValue.toStdString();
|
||||
if (partial == Format::UNALTERED) { // prefix + unit subsystem string + suffix
|
||||
return formatPrefix.toStdString() +
|
||||
qUserString.toStdString() +
|
||||
formatSuffix.toStdString();
|
||||
|
||||
if (partial == Format::UNALTERED) {
|
||||
return basicString;
|
||||
}
|
||||
else if (partial == Format::FORMATTED) {
|
||||
|
||||
if (partial == Format::FORMATTED) {
|
||||
std::string unitStr {};
|
||||
|
||||
if (angularMeasure) {
|
||||
//always insert unit after value
|
||||
return formatPrefix.toStdString() + formattedValueString + "°" +
|
||||
formatSuffix.toStdString();
|
||||
unitStr = "°";
|
||||
}
|
||||
else if (m_dimension->showUnits() || areaMeasure){
|
||||
if (isDim && m_dimension->haveTolerance()) {
|
||||
//unit will be included in tolerance so don't repeat it here
|
||||
return formatPrefix.toStdString() +
|
||||
formattedValueString +
|
||||
formatSuffix.toStdString();
|
||||
}
|
||||
else {
|
||||
//no tolerance, so we need to include unit
|
||||
return formatPrefix.toStdString() +
|
||||
formattedValueString + " " +
|
||||
qBasicUnit.toStdString() +
|
||||
formatSuffix.toStdString();
|
||||
}
|
||||
}
|
||||
else {
|
||||
//showUnits is false
|
||||
return formatPrefix.toStdString() +
|
||||
formattedValueString +
|
||||
formatSuffix.toStdString();
|
||||
else if ((m_dimension->showUnits() || areaMeasure)
|
||||
&& !(isDim && m_dimension->haveTolerance())) {
|
||||
unitStr = " " + qBasicUnit;
|
||||
}
|
||||
|
||||
return formatPrefix + formattedValueString + unitStr + formatSuffix;
|
||||
}
|
||||
else if (partial == Format::UNIT) {
|
||||
if (angularMeasure) {
|
||||
return qBasicUnit.toStdString();
|
||||
}
|
||||
else if (m_dimension->showUnits() || areaMeasure) {
|
||||
return qBasicUnit.toStdString();
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (partial == Format::UNIT) {
|
||||
return angularMeasure || m_dimension->showUnits() || areaMeasure ? qBasicUnit : "";
|
||||
}
|
||||
|
||||
return formattedValueString;
|
||||
@@ -368,13 +334,10 @@ QString DimensionFormatter::formatValueToSpec(const double value, QString format
|
||||
|
||||
bool DimensionFormatter::isNumericFormat(const QString& formatSpecifier) const
|
||||
{
|
||||
QRegularExpression rxFormat(QStringLiteral("%[+-]?[0-9]*\\.*[0-9]*[aefgwAEFGW]")); //printf double format spec
|
||||
//printf double format spec
|
||||
const QRegularExpression rxFormat(QStringLiteral("%[+-]?[0-9]*\\.*[0-9]*[aefgwAEFGW]"));
|
||||
QRegularExpressionMatch rxMatch;
|
||||
int pos = formatSpecifier.indexOf(rxFormat, 0, &rxMatch);
|
||||
if (pos != -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return formatSpecifier.indexOf(rxFormat, 0, &rxMatch) != -1;
|
||||
}
|
||||
|
||||
//TODO: similar code here and above
|
||||
|
||||
@@ -41,28 +41,28 @@ public:
|
||||
UNIT // return only the unit of measure
|
||||
};
|
||||
|
||||
DimensionFormatter() {}
|
||||
DimensionFormatter(DrawViewDimension* dim) { m_dimension = dim; }
|
||||
DimensionFormatter() = default;
|
||||
explicit DimensionFormatter(DrawViewDimension* dim)
|
||||
: m_dimension {dim}
|
||||
{}
|
||||
~DimensionFormatter() = default;
|
||||
|
||||
//void setDimension(DrawViewDimension* dim) { m_dimension = dim; }
|
||||
bool isMultiValueSchema() const;
|
||||
std::string formatValue(const qreal value,
|
||||
const QString& qFormatSpec,
|
||||
const Format partial,
|
||||
const bool isDim) const;
|
||||
std::string getFormattedToleranceValue(const Format partial) const;
|
||||
std::pair<std::string, std::string> getFormattedToleranceValues(const Format partial) const;
|
||||
std::string getFormattedDimensionValue(const Format partial) const;
|
||||
std::string formatValue(qreal value, const QString& qFormatSpec, Format partial, bool isDim) const;
|
||||
std::string getFormattedToleranceValue(Format partial) const;
|
||||
std::pair<std::string, std::string> getFormattedToleranceValues(Format partial) const;
|
||||
std::string getFormattedDimensionValue(Format partial) const;
|
||||
QStringList getPrefixSuffixSpec(const QString& fSpec) const;
|
||||
std::string getDefaultFormatSpec(bool isToleranceFormat) const;
|
||||
bool isTooSmall(const double value, const QString& formatSpec) const;
|
||||
QString formatValueToSpec(const double value, QString formatSpecifier) const;
|
||||
bool isNumericFormat(const QString& formatSpecifier) const;
|
||||
|
||||
private:
|
||||
DrawViewDimension* m_dimension;
|
||||
bool isTooSmall(double value, const QString& formatSpec) const;
|
||||
QString formatValueToSpec(double value, QString formatSpecifier) const;
|
||||
bool isNumericFormat(const QString& formatSpecifier) const;
|
||||
|
||||
DrawViewDimension* m_dimension {nullptr};
|
||||
};
|
||||
|
||||
} //end namespace TechDraw
|
||||
} // end namespace TechDraw
|
||||
#endif
|
||||
|
||||
@@ -96,9 +96,9 @@ class UnitBasicCases(unittest.TestCase):
|
||||
qu2 = FreeCAD.Units.Quantity("m/s")
|
||||
self.assertTrue(qu1 / qu2, 1)
|
||||
|
||||
def testSchemes(self):
|
||||
schemes = FreeCAD.Units.listSchemas()
|
||||
num = len(schemes)
|
||||
def testSchemas(self):
|
||||
schemas = FreeCAD.Units.listSchemas()
|
||||
num = len(schemas)
|
||||
|
||||
psi = FreeCAD.Units.parseQuantity("1psi")
|
||||
for i in range(num):
|
||||
@@ -108,7 +108,7 @@ class UnitBasicCases(unittest.TestCase):
|
||||
1,
|
||||
v.Value,
|
||||
msg='Failed with "{0}" scheme: {1} != 1 (delta: {2})'.format(
|
||||
schemes[i], v.Value, self.delta
|
||||
schemas[i], v.Value, self.delta
|
||||
),
|
||||
delta=self.delta,
|
||||
)
|
||||
@@ -121,7 +121,7 @@ class UnitBasicCases(unittest.TestCase):
|
||||
1,
|
||||
v.Value,
|
||||
msg='Failed with "{0}" scheme: {1} != 1 (delta: {2})'.format(
|
||||
schemes[i], v.Value, self.delta
|
||||
schemas[i], v.Value, self.delta
|
||||
),
|
||||
delta=self.delta,
|
||||
)
|
||||
@@ -135,7 +135,7 @@ class UnitBasicCases(unittest.TestCase):
|
||||
1,
|
||||
v.Value,
|
||||
msg='Failed with "{0}" scheme: {1} != 1 (delta: {2})'.format(
|
||||
schemes[i], v.Value, self.delta
|
||||
schemas[i], v.Value, self.delta
|
||||
),
|
||||
delta=self.delta,
|
||||
)
|
||||
@@ -146,12 +146,12 @@ class UnitBasicCases(unittest.TestCase):
|
||||
if issubclass(type(getattr(FreeCAD.Units, i)), FreeCAD.Units.Quantity):
|
||||
quantities.append(i)
|
||||
|
||||
schemes = FreeCAD.Units.listSchemas()
|
||||
schemas = FreeCAD.Units.listSchemas()
|
||||
for i in quantities:
|
||||
q1 = getattr(FreeCAD.Units, i)
|
||||
q1 = FreeCAD.Units.Quantity(q1)
|
||||
q1.Format = {"Precision": 16}
|
||||
for idx, val in enumerate(schemes):
|
||||
for idx, val in enumerate(schemas):
|
||||
[t, amountPerUnit, unit] = FreeCAD.Units.schemaTranslate(q1, idx)
|
||||
try:
|
||||
q2 = FreeCAD.Units.Quantity(t)
|
||||
|
||||
Reference in New Issue
Block a user