Commit ad405165 authored by Andre Heinecke's avatar Andre Heinecke Committed by Albert Astals Cid
Browse files

Add AFNumber_Format and l10n AFSimple_Calculate

This adds utility functions to util to work with QLocale
for formatting and Number handling.

At least until we support AFNumber_Keystroke to restrict
what a user enters in Number input fields it is good
behavior to expect the user to enter Numbers in the system's
Locale.

AFNumber_Format is new for formatting and uses the
Locale util functions.
parent 49385366
Pipeline #16162 passed with stage
in 17 minutes and 4 seconds
......@@ -45,6 +45,14 @@ void CalculateTextTest::cleanupTestCase()
void CalculateTextTest::testSimpleCalculate()
{
// Force consistent locale
QLocale locale(QStringLiteral("en_US.UTF-8"));
if (locale == QLocale::c())
{
locale = QLocale(QLocale::English, QLocale::UnitedStates);
}
QLocale::setDefault(locale);
const QString testFile = QStringLiteral( KDESRCDIR "data/simpleCalculate.pdf" );
QMimeDatabase db;
const QMimeType mime = db.mimeTypeForFile( testFile );
......@@ -79,7 +87,7 @@ void CalculateTextTest::testSimpleCalculate()
// Verify the results
QCOMPARE (fields[QStringLiteral ("Sum")]->text(), QStringLiteral( "60" ));
QCOMPARE (fields[QStringLiteral ("AVG")]->text(), QStringLiteral( "20" ));
QCOMPARE (fields[QStringLiteral ("Prod")]->text(), QStringLiteral( "6000" ));
QCOMPARE (fields[QStringLiteral ("Prod")]->text(), QStringLiteral( "6,000" ));
QCOMPARE (fields[QStringLiteral ("Min")]->text(), QStringLiteral( "10" ));
QCOMPARE (fields[QStringLiteral ("Max")]->text(), QStringLiteral( "30" ));
......
......@@ -27,7 +27,7 @@ function AFSimple_Calculate( cFunction, cFields )
for (i = 0; i < cFields.length; i++)
{
var field = Doc.getField( cFields[i] );
var val = Number( field.value );
var val = util.stringToNumber( field.value );
if ( cFunction === "SUM" || cFunction === "AVG" )
{
......@@ -58,6 +58,75 @@ function AFSimple_Calculate( cFunction, cFields )
ret /= cFields.length;
}
event.value = util.numberToString( ret, "g", 32 );
}
/** AFNumber_Format
*
* Formats event.value based on parameters.
*
* Parameter description based on Acrobat Help:
*
* nDec is the number of places after the decimal point.
*
* sepStyle is an integer denoting whether to use a separator
* If it is 1 comma should be used.
* If it is 2 a dot should be used.
* The decimal seperator is changed accordingly.
*
* nexStyle is the formatting used for negative numbers: - not implemented.
* 0 = MinusBlack
* 1 = Red
* 2 = ParensBlack
* 3 = ParensRed
*
* currStyle is the currency style - not used.
*
* strCurrency is the currency symbol.
*
* bCurrencyPrepend is true to prepend the currency symbol;
* false to display on the end of the number.
*/
function AFNumber_Format( nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend )
{
if ( !event.value )
{
return;
}
var ret;
var localized = util.stringToNumber( event.value );
if ( sepStyle === 2 )
{
// Use de_DE as the locale for the dot seperator format
ret = util.numberToString( localized, "f", nDec, 'de_DE' );
}
else
{
// Otherwise US
ret = util.numberToString( localized, "f", nDec, 'en_US' );
}
if ( sepStyle === 0 )
{
// No seperators. Remove all commas from the US format.
ret.replace( /,/g, '' );
}
if ( strCurrency )
{
if ( bCurrencyPrepend )
{
ret = strCurrency + ret;
}
else
{
ret = ret + strCurrency;
}
}
event.value = ret;
}
......
......@@ -20,6 +20,8 @@
#include <QRegularExpression>
#include <QDateTime>
#include <cmath>
using namespace Okular;
static KJSPrototype *g_utilProto;
......@@ -112,6 +114,84 @@ static KJSObject printd( KJSContext *context, void *,
return KJSString( defaultLocale.toString( date, format ) );
}
/** Converts a Number to a String using l10n
*
* String numberToString( Number number, String format = 'g', int precision = 6,
* String LocaleName = system )
*/
static KJSObject numberToString ( KJSContext *context, void *,
const KJSArguments &arguments )
{
if ( arguments.count() < 1 )
{
return context->throwException( QStringLiteral( "Invalid arguments" ) );
}
const double number = arguments.at( 0 ).toNumber( context );
if ( std::isnan( number ) )
{
return KJSString( "NaN" );
}
QChar format = QLatin1Char( 'g' );
if ( arguments.count() >= 2 )
{
const QString fmt = arguments.at( 1 ).toString( context );
if ( !fmt.isEmpty() )
{
format = fmt[0];
}
}
int precision = 6;
if ( arguments.count() >= 3 )
{
precision = arguments.at( 2 ).toInt32( context );
}
QLocale locale;
if ( arguments.count() == 4 )
{
locale = QLocale( arguments.at( 3 ).toString( context ) );
}
return KJSString( locale.toString( number, format.toLatin1(), precision ) );
}
/** Converts a String to a Number using l10n.
*
* Number stringToNumber( String number, String LocaleName = system ) */
static KJSObject stringToNumber ( KJSContext *context, void *,
const KJSArguments &arguments )
{
if ( arguments.count() < 1 )
{
return context->throwException( QStringLiteral( "Invalid arguments" ) );
}
const QString number = arguments.at( 0 ).toString( context );
if ( number.isEmpty() )
{
return KJSNumber( 0 );
}
QLocale locale;
if ( arguments.count() == 2 )
{
locale = QLocale( arguments.at( 1 ).toString( context ) );
}
bool ok;
const double converted = locale.toDouble( number, &ok );
if ( !ok )
{
return KJSNumber( std::nan( "" ) );
}
return KJSNumber( converted );
}
void JSUtil::initType( KJSContext *ctx )
{
static bool initialized = false;
......@@ -122,6 +202,8 @@ void JSUtil::initType( KJSContext *ctx )
g_utilProto = new KJSPrototype();
g_utilProto->defineFunction( ctx, QStringLiteral("crackURL"), crackURL );
g_utilProto->defineFunction( ctx, QStringLiteral("printd"), printd );
g_utilProto->defineFunction( ctx, QStringLiteral("stringToNumber"), stringToNumber );
g_utilProto->defineFunction( ctx, QStringLiteral("numberToString"), numberToString );
}
KJSObject JSUtil::object( KJSContext *ctx )
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment