diff --git a/resources/function_help/json/format_number b/resources/function_help/json/format_number index 2b11a5d3090..16e11d1ffc7 100644 --- a/resources/function_help/json/format_number +++ b/resources/function_help/json/format_number @@ -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'"} ] } diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index 935dc246959..7df781317a8 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -4364,29 +4364,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 ); } @@ -5879,7 +5877,7 @@ const QList &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" ) ) diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp index 3a22958900c..18f2a02620b 100644 --- a/tests/src/core/testqgsexpression.cpp +++ b/tests/src/core/testqgsexpression.cpp @@ -1246,6 +1246,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 );