summaryrefslogtreecommitdiff
path: root/i18npool/source/nativenumber/nativenumbersupplier.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'i18npool/source/nativenumber/nativenumbersupplier.cxx')
-rw-r--r--i18npool/source/nativenumber/nativenumbersupplier.cxx107
1 files changed, 91 insertions, 16 deletions
diff --git a/i18npool/source/nativenumber/nativenumbersupplier.cxx b/i18npool/source/nativenumber/nativenumbersupplier.cxx
index 6dc7c792c931..f3c40a2b7d61 100644
--- a/i18npool/source/nativenumber/nativenumbersupplier.cxx
+++ b/i18npool/source/nativenumber/nativenumbersupplier.cxx
@@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <i18nlangtag/languagetag.hxx>
#include <i18nlangtag/mslangid.hxx>
#include <rtl/ustrbuf.hxx>
#include <sal/macros.h>
@@ -24,8 +25,12 @@
#include <localedata.hxx>
#include "data/numberchar.h"
#include <comphelper/string.hxx>
+#include <comphelper/processfactory.hxx>
#include <cppuhelper/supportsservice.hxx>
+#include <map>
#include <memory>
+#include <unordered_map>
+#include <com/sun/star/linguistic2/NumberText.hpp>
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::i18n;
@@ -250,7 +255,10 @@ OUString AsciiToNative( const OUString& inStr, sal_Int32 nCount,
}
return aRet;
}
-static void NativeToAscii_numberMaker(sal_Int16 max, sal_Int16 prev, const sal_Unicode *str,
+
+namespace
+{
+void NativeToAscii_numberMaker(sal_Int16 max, sal_Int16 prev, const sal_Unicode *str,
sal_Int32& i, sal_Int32 nCount, sal_Unicode *dst, sal_Int32& count, Sequence< sal_Int32 >& offset, bool useOffset,
OUString& numberChar, OUString& multiplierChar)
{
@@ -300,7 +308,7 @@ static void NativeToAscii_numberMaker(sal_Int16 max, sal_Int16 prev, const sal_U
}
/// @throws RuntimeException
-static OUString NativeToAscii(const OUString& inStr,
+OUString NativeToAscii(const OUString& inStr,
sal_Int32 nCount, Sequence< sal_Int32 >& offset, bool useOffset )
{
OUString aRet;
@@ -374,7 +382,7 @@ static OUString NativeToAscii(const OUString& inStr,
return aRet;
}
-static const Number natnum4[4] = {
+const Number natnum4[4] = {
{ NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh], 0,
ExponentCount_6_CJK, MultiplierExponent_6_CJK },
{ NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh_TW], 0,
@@ -385,7 +393,7 @@ static const Number natnum4[4] = {
ExponentCount_6_CJK, MultiplierExponent_6_CJK },
};
-static const Number natnum5[4] = {
+const Number natnum5[4] = {
{ NumberChar_Upper_zh, MultiplierChar_6_CJK[Multiplier_Upper_zh], 0,
ExponentCount_6_CJK, MultiplierExponent_6_CJK },
{ NumberChar_Upper_zh_TW, MultiplierChar_6_CJK[Multiplier_Upper_zh_TW], 0,
@@ -396,7 +404,7 @@ static const Number natnum5[4] = {
ExponentCount_6_CJK, MultiplierExponent_6_CJK },
};
-static const Number natnum6[4] = {
+const Number natnum6[4] = {
{ NumberChar_FullWidth, MultiplierChar_6_CJK[Multiplier_Lower_zh], 0,
ExponentCount_6_CJK, MultiplierExponent_6_CJK },
{ NumberChar_FullWidth, MultiplierChar_6_CJK[Multiplier_Lower_zh_TW], 0,
@@ -407,7 +415,7 @@ static const Number natnum6[4] = {
ExponentCount_6_CJK, MultiplierExponent_6_CJK },
};
-static const Number natnum7[4] = {
+const Number natnum7[4] = {
{ NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh], NUMBER_OMIT_ALL,
ExponentCount_6_CJK, MultiplierExponent_6_CJK },
{ NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh_TW], NUMBER_OMIT_ALL,
@@ -418,7 +426,7 @@ static const Number natnum7[4] = {
ExponentCount_6_CJK, MultiplierExponent_6_CJK },
};
-static const Number natnum8[4] = {
+const Number natnum8[4] = {
{ NumberChar_Upper_zh, MultiplierChar_6_CJK[Multiplier_Upper_zh], NUMBER_OMIT_ALL,
ExponentCount_6_CJK, MultiplierExponent_6_CJK },
{ NumberChar_Upper_zh_TW, MultiplierChar_6_CJK[Multiplier_Upper_zh_TW], NUMBER_OMIT_ALL,
@@ -429,14 +437,14 @@ static const Number natnum8[4] = {
ExponentCount_6_CJK, MultiplierExponent_6_CJK },
};
-static const Number natnum10 = { NumberChar_Hangul_ko, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ZERO,
+const Number natnum10 = { NumberChar_Hangul_ko, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ZERO,
ExponentCount_6_CJK, MultiplierExponent_6_CJK };
-static const Number natnum11 = { NumberChar_Hangul_ko, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ALL,
+const Number natnum11 = { NumberChar_Hangul_ko, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ALL,
ExponentCount_6_CJK, MultiplierExponent_6_CJK };
//! ATTENTION: Do not change order of elements!
//! Append new languages to the end of the list!
-static const sal_Char *natnum1Locales[] = {
+const sal_Char *natnum1Locales[] = {
"zh_CN",
"zh_TW",
"ja",
@@ -464,11 +472,11 @@ static const sal_Char *natnum1Locales[] = {
"fa",
"cu"
};
-static sal_Int16 nbOfLocale = SAL_N_ELEMENTS(natnum1Locales);
+sal_Int16 nbOfLocale = SAL_N_ELEMENTS(natnum1Locales);
//! ATTENTION: Do not change order of elements!
//! Number and order must match elements of natnum1Locales!
-static const sal_Int16 natnum1[] = {
+const sal_Int16 natnum1[] = {
NumberChar_Lower_zh,
NumberChar_Lower_zh,
NumberChar_Modern_ja,
@@ -496,20 +504,20 @@ static const sal_Int16 natnum1[] = {
NumberChar_EastIndic_ar,
NumberChar_cu
};
-static const sal_Int16 sizeof_natnum1 = SAL_N_ELEMENTS(natnum1);
+const sal_Int16 sizeof_natnum1 = SAL_N_ELEMENTS(natnum1);
//! ATTENTION: Do not change order of elements!
//! Order must match first elements of natnum1Locales!
-static const sal_Int16 natnum2[] = {
+const sal_Int16 natnum2[] = {
NumberChar_Upper_zh,
NumberChar_Upper_zh_TW,
NumberChar_Traditional_ja,
NumberChar_Upper_ko,
NumberChar_he
};
-static const sal_Int16 sizeof_natnum2 = SAL_N_ELEMENTS(natnum2);
+const sal_Int16 sizeof_natnum2 = SAL_N_ELEMENTS(natnum2);
-static sal_Int16 getLanguageNumber( const Locale& rLocale)
+sal_Int16 getLanguageNumber( const Locale& rLocale)
{
// return zh_TW for TW, HK and MO, return zh_CN for other zh locales.
if (rLocale.Language == "zh") return MsLangId::isTraditionalChinese(rLocale) ? 1 : 0;
@@ -521,12 +529,76 @@ static sal_Int16 getLanguageNumber( const Locale& rLocale)
return -1;
}
+OUString getNumberText(const Locale& aLocale, sal_Int16 numType, const OUString& rNumberString)
+{
+ assert(numType == NativeNumberMode::NATNUM12 || numType == NativeNumberMode::NATNUM13
+ || numType == NativeNumberMode::NATNUM14);
+
+ sal_Int32 i, count = 0;
+ const sal_Int32 len = rNumberString.getLength();
+ const sal_Unicode* src = rNumberString.getStr();
+
+ OUStringBuffer sBuf(len);
+ for (i = 0; i < len; i++)
+ {
+ sal_Unicode ch = src[i];
+ if (isNumber(ch))
+ {
+ ++count;
+ sBuf.append(ch);
+ }
+ else if (isSeparator(ch) && count > 0)
+ continue;
+ else if (isMinus(ch) && count == 0)
+ sBuf.append(ch);
+ else
+ break;
+ }
+
+ if (count == 0)
+ return rNumberString;
+
+ OUString aNumberStr = sBuf.makeStringAndClear();
+
+ static auto xNumberText
+ = css::linguistic2::NumberText::create(comphelper::getProcessComponentContext());
+ OUString aLoc = LanguageTag::convertToBcp47(aLocale);
+ OUString numbertext_prefix;
+ if (numType == NativeNumberMode::NATNUM14)
+ numbertext_prefix = "ordinal-number ";
+ else if (numType == NativeNumberMode::NATNUM13)
+ numbertext_prefix = "ordinal ";
+ // Several hundreds of headings could result typing lags because
+ // of the continuous update of the multiple number names during typing.
+ // We fix this by buffering the result of the conversion.
+ static std::unordered_map<OUString, std::map<OUString, OUString>> aBuff;
+ auto& rItems = aBuff[aNumberStr];
+ auto& rItem = rItems[numbertext_prefix + aLoc];
+ if (rItem.isEmpty())
+ {
+ rItem = xNumberText->getNumberText(numbertext_prefix + aNumberStr, aLocale);
+ // use number at missing number to text conversion
+ if (rItem.isEmpty())
+ rItem = aNumberStr;
+ }
+ OUString sResult = rItem;
+ if (i < len)
+ sResult += rNumberString.copy(i);
+ return sResult;
+}
+}
+
OUString NativeNumberSupplierService::getNativeNumberString(const OUString& aNumberString, const Locale& rLocale,
sal_Int16 nNativeNumberMode, Sequence< sal_Int32 >& offset)
{
if (!isValidNatNum(rLocale, nNativeNumberMode))
return aNumberString;
+ if (nNativeNumberMode == NativeNumberMode::NATNUM12
+ || nNativeNumberMode == NativeNumberMode::NATNUM13
+ || nNativeNumberMode == NativeNumberMode::NATNUM14)
+ return getNumberText(rLocale, nNativeNumberMode, aNumberString);
+
sal_Int16 langnum = getLanguageNumber(rLocale);
if (langnum == -1)
return aNumberString;
@@ -664,6 +736,9 @@ sal_Bool SAL_CALL NativeNumberSupplierService::isValidNatNum( const Locale& rLoc
switch (nNativeNumberMode) {
case NativeNumberMode::NATNUM0: // Ascii
case NativeNumberMode::NATNUM3: // Char, FullWidth
+ case NativeNumberMode::NATNUM12: // Cardinal number names (one, two, three, ...)
+ case NativeNumberMode::NATNUM13: // Ordinal number names (first, second, third, ...)
+ case NativeNumberMode::NATNUM14: // Ordinal indicators (1st, 2nd, 3rd, ...)
return true;
case NativeNumberMode::NATNUM1: // Char, Lower
return (langnum >= 0);