Skip to content
Permalink
Browse files

[expression] Add optional language parameter to format_number() to co…

…ntrol locale across different systems

(cherry picked from commit cbd3068)
  • Loading branch information
nirvn authored and nyalldawson committed Jun 19, 2020
1 parent a1342f5 commit 623c263b60bb7a0cb85751231fd31086f1a96d2d
@@ -1,9 +1,10 @@
{
"name": "format_number",
"type": "function",
"description": "Returns a number formatted with the locale separator for thousands. Also truncates the number to the number of supplied places.",
"description": "Returns a number formatted with the locale separator for thousands. Also truncates the decimal places to the number of supplied places.",
"arguments": [ {"arg":"number","description":"number to be formatted"},
{"arg":"places","description":"integer representing the number of decimal places to truncate the string to."}],
{"arg":"places","description":"integer representing the number of decimal places to truncate the string to."},
{"arg":"language","optional":true,"description":"language (lowercase, two- or three-letter, ISO 639 language code) used to format the number into a string"}],
"examples": [ { "expression":"format_number(10000000.332,2)", "returns":"'10,000,000.33'"}
]
}
@@ -3875,29 +3875,27 @@ static QVariant fcnPi( const QVariantList &values, const QgsExpressionContext *,

static QVariant fcnFormatNumber( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
const double value = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
const int places = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
if ( places < 0 )
{
parent->setEvalErrorString( QObject::tr( "Number of places must be positive" ) );
return QVariant();
}
QLocale locale = QLocale();

QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
return locale.toString( value, 'f', places );
}

static QVariant fcnFormatDate( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );
const QDateTime datetime = QgsExpressionUtils::getDateTimeValue( values.at( 0 ), parent );
const QString format = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
const QString language = QgsExpressionUtils::getStringValue( values.at( 2 ), parent );

QLocale locale = QLocale();
if ( !language.isEmpty() )
{
locale = QLocale( language );
}
QLocale locale = !language.isEmpty() ? QLocale( language ) : QLocale();
return locale.toString( datetime, format );
}

@@ -5255,7 +5253,7 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
<< new QgsStaticExpressionFunction( QStringLiteral( "rpad" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "width" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "fill" ) ), fcnRPad, QStringLiteral( "String" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "lpad" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "width" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "fill" ) ), fcnLPad, QStringLiteral( "String" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "format" ), -1, fcnFormatString, QStringLiteral( "String" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "format_number" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "number" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "places" ) ), fcnFormatNumber, QStringLiteral( "String" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "format_number" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "number" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "places" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "language" ), true, QVariant() ), fcnFormatNumber, QStringLiteral( "String" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "format_date" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "datetime" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "format" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "language" ), true, QVariant() ), fcnFormatDate, QStringList() << QStringLiteral( "String" ) << QStringLiteral( "Date and Time" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "color_grayscale_average" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "color" ) ), fcnColorGrayscaleAverage, QStringLiteral( "Color" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "color_mix_rgb" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "color1" ) )
@@ -1153,6 +1153,11 @@ class TestQgsExpression: public QObject
QTest::newRow( "format_number large" ) << "format_number(9000000.0,0)" << false << QVariant( "9,000,000" );
QTest::newRow( "format_number many decimals" ) << "format_number(123.45600,4)" << false << QVariant( "123.4560" );
QTest::newRow( "format_number no decimals" ) << "format_number(1999.567,0)" << false << QVariant( "2,000" );
#if QT_VERSION >= QT_VERSION_CHECK( 5, 12, 0 )
QTest::newRow( "format_number language parameter" ) << "format_number(123457.00,2,'fr')" << false << QVariant( "123\u202F457,00" );
#else
QTest::newRow( "format_number language parameter" ) << "format_number(123457.00,2,'fr')" << false << QVariant( "123\u00A0457,00" );
#endif
QTest::newRow( "lower" ) << "lower('HeLLo')" << false << QVariant( "hello" );
QTest::newRow( "upper" ) << "upper('HeLLo')" << false << QVariant( "HELLO" );
QTest::newRow( "length" ) << "length('HeLLo')" << false << QVariant( 5 );

0 comments on commit 623c263

Please sign in to comment.
You can’t perform that action at this time.