diff options
author | Cédric Bosdonnat <cedricbosdo@openoffice.org> | 2011-04-07 13:33:50 +0200 |
---|---|---|
committer | Cédric Bosdonnat <cedricbosdo@openoffice.org> | 2011-04-07 14:05:37 +0200 |
commit | ab40888bbb94273872a349b0b3565750596b4f3c (patch) | |
tree | fea61eb4d6c70ed6004912ae14d90266b91a25b7 /i18npool/source | |
parent | 92935bed219b8cc07c15a255fdfbe14a4746b2f6 (diff) |
i#20348: made the ordinal suffixe autocorrection internationalized
Diffstat (limited to 'i18npool/source')
-rw-r--r-- | i18npool/source/ordinalsuffix/ordinalsuffix.cxx | 85 |
1 files changed, 50 insertions, 35 deletions
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 <string.h> #include "ordinalsuffix.hxx" +#include <unicode/rbnf.h> +#include <unicode/normlzr.h> + +#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<const sal_Unicode *>( 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 ) |