From 2d33246c1d6d3ad1991de927f397af837ac80d49 Mon Sep 17 00:00:00 2001 From: Cédric Bosdonnat Date: Thu, 7 Apr 2011 13:33:50 +0200 Subject: i#20348: made the ordinal suffixe autocorrection internationalized --- i18npool/inc/ordinalsuffix.hxx | 2 +- i18npool/source/ordinalsuffix/ordinalsuffix.cxx | 85 +++++++++++++++---------- 2 files changed, 51 insertions(+), 36 deletions(-) (limited to 'i18npool') diff --git a/i18npool/inc/ordinalsuffix.hxx b/i18npool/inc/ordinalsuffix.hxx index ef3328b0971d..6116047b0efd 100644 --- a/i18npool/inc/ordinalsuffix.hxx +++ b/i18npool/inc/ordinalsuffix.hxx @@ -45,7 +45,7 @@ class OrdinalSuffix : public cppu::WeakImplHelper2 virtual ~OrdinalSuffix(); // XOrdinalSuffix - virtual rtl::OUString SAL_CALL getOrdinalSuffix( sal_Int32 nNumber, const com::sun::star::lang::Locale &rLocale) throw(com::sun::star::uno::RuntimeException); + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getOrdinalSuffix( sal_Int32 nNumber, const com::sun::star::lang::Locale &rLocale ) throw(com::sun::star::uno::RuntimeException); // XServiceInfo virtual rtl::OUString SAL_CALL getImplementationName() throw(com::sun::star::uno::RuntimeException); diff --git a/i18npool/source/ordinalsuffix/ordinalsuffix.cxx b/i18npool/source/ordinalsuffix/ordinalsuffix.cxx index f541553a9efa..3e8158cd8209 100644 --- a/i18npool/source/ordinalsuffix/ordinalsuffix.cxx +++ b/i18npool/source/ordinalsuffix/ordinalsuffix.cxx @@ -32,10 +32,14 @@ #include #include "ordinalsuffix.hxx" +#include +#include + +#define CSTR( ouStr ) rtl::OUStringToOString( ouStr, RTL_TEXTENCODING_UTF8 ).getStr( ) using namespace ::com::sun::star::i18n; using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::lang; +using namespace ::com::sun::star; using namespace ::rtl; namespace com { namespace sun { namespace star { namespace i18n { @@ -52,50 +56,61 @@ OrdinalSuffix::~OrdinalSuffix() } -static OUString getOrdinalSuffixEn( sal_Int32 nNumber ) +/* + * For this method to properly return the ordinal suffix for other locales + * than english ones, ICU 4.2+ has to be used. + */ +uno::Sequence< OUString > SAL_CALL OrdinalSuffix::getOrdinalSuffix( sal_Int32 nNumber, + const lang::Locale &aLocale ) throw( RuntimeException ) { - OUString retValue; - - switch( labs( nNumber ) % 100 ) + uno::Sequence< OUString > retValue; + + // Get the value from ICU + UErrorCode nCode = U_ZERO_ERROR; + const icu::Locale rIcuLocale( + CSTR( aLocale.Language ), + CSTR( aLocale.Country ), + CSTR( aLocale.Variant ) ); + icu::RuleBasedNumberFormat formatter( + icu::URBNF_ORDINAL, rIcuLocale, nCode ); + + if ( U_SUCCESS( nCode ) ) { - case 11: case 12: case 13: - retValue = OUString(RTL_CONSTASCII_USTRINGPARAM("th")); - break; - default: - switch( nNumber % 10 ) + int32_t nRuleSets = formatter.getNumberOfRuleSetNames( ); + for ( int32_t i = 0; i < nRuleSets; i++ ) + { + icu::UnicodeString ruleSet = formatter.getRuleSetName( i ); + // format the string + icu::UnicodeString icuRet; + icu::FieldPosition icuPos; + formatter.format( (int32_t)nNumber, ruleSet, icuRet, icuPos, nCode ); + + if ( U_SUCCESS( nCode ) ) { - case 1: - retValue = OUString(RTL_CONSTASCII_USTRINGPARAM("st")); - break; - case 2: - retValue = OUString(RTL_CONSTASCII_USTRINGPARAM("nd")); - break; - case 3: - retValue = OUString(RTL_CONSTASCII_USTRINGPARAM("rd")); - break; - default: - retValue = OUString(RTL_CONSTASCII_USTRINGPARAM("th")); - break; + // Apply NFKC normalization to get normal letters + icu::UnicodeString normalized; + nCode = U_ZERO_ERROR; + icu::Normalizer::normalize( icuRet, UNORM_NFKC, 0, normalized, nCode ); + if ( U_SUCCESS( nCode ) && ( normalized != icuRet ) ) + { + // Convert the normalized UnicodeString to OUString + OUString sValue( reinterpret_cast( normalized.getBuffer( ) ), normalized.length() ); + + // Remove the number to get the prefix + sal_Int32 len = OUString::valueOf( nNumber ).getLength( ); + + sal_Int32 newLength = retValue.getLength() + 1; + retValue.realloc( newLength ); + retValue[ newLength - 1 ] = sValue.copy( len ); + } } - break; + } } return retValue; } -OUString SAL_CALL OrdinalSuffix::getOrdinalSuffix( sal_Int32 nNumber, - const Locale &aLocale ) throw( RuntimeException ) -{ - OUString retValue; - - if (aLocale.Language.equalsAsciiL("en",2)) - retValue = getOrdinalSuffixEn( nNumber ); - - return retValue; -} - - const sal_Char cOrdinalSuffix[] = "com.sun.star.i18n.OrdinalSuffix"; OUString SAL_CALL OrdinalSuffix::getImplementationName(void) throw( RuntimeException ) -- cgit