From: Hwankyu Jhun Date: Tue, 14 Nov 2017 00:30:03 +0000 (+0900) Subject: [Common] Fix setting current CultureInfo X-Git-Tag: 5.0.0-preview1-00378^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F28%2F159928%2F22;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git [Common] Fix setting current CultureInfo Change-Id: Ia8436defb1e51cc395e6598263bf9bddedb79ba0 Signed-off-by: Hwankyu Jhun --- diff --git a/src/Tizen.Applications.Common/Interop/Interop.Icu.cs b/src/Tizen.Applications.Common/Interop/Interop.Icu.cs new file mode 100644 index 0000000..d5771c4 --- /dev/null +++ b/src/Tizen.Applications.Common/Interop/Interop.Icu.cs @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +using Tizen.Applications; + +internal static partial class Interop +{ + internal static partial class Icu + { + [DllImport(Libraries.Icuuc, EntryPoint = "uloc_canonicalize")] + internal static extern Int32 Canonicalize(string localeID, [Out] StringBuilder name, Int32 nameCapacity, out int err); + + [DllImport(Libraries.Icuuc, EntryPoint = "uloc_getLanguage")] + internal static extern Int32 GetLanguage(string localeID, [Out] StringBuilder language, Int32 languageCapacity, out int err); + + [DllImport(Libraries.Icuuc, EntryPoint = "uloc_getScript")] + internal static extern Int32 GetScript(string localeID, [Out] StringBuilder script, Int32 scriptCapacity, out int err); + + [DllImport(Libraries.Icuuc, EntryPoint = "uloc_getCountry")] + internal static extern Int32 GetCountry(string localeID, [Out] StringBuilder country, Int32 countryCapacity, out int err); + + [DllImport(Libraries.Icuuc, EntryPoint = "uloc_getVariant")] + internal static extern Int32 GetVariant(string localeID, [Out] StringBuilder variant, Int32 variantCapacity, out int err); + } +} diff --git a/src/Tizen.Applications.Common/Interop/Interop.Libraries.cs b/src/Tizen.Applications.Common/Interop/Interop.Libraries.cs old mode 100755 new mode 100644 index 8a417c6..227d014 --- a/src/Tizen.Applications.Common/Interop/Interop.Libraries.cs +++ b/src/Tizen.Applications.Common/Interop/Interop.Libraries.cs @@ -27,5 +27,6 @@ internal static partial class Interop public const string Glib = "libglib-2.0.so.0"; public const string Libc = "libc.so.6"; public const string Application = "libcapi-appfw-application.so.0"; + public const string Icuuc = "libicuuc.so"; } } diff --git a/src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs b/src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs index d21efb1..2917cc7 100644 --- a/src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs +++ b/src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs @@ -16,6 +16,7 @@ using System; using System.Globalization; +using System.Text; using Tizen.Applications.CoreBackend; namespace Tizen.Applications @@ -239,69 +240,168 @@ namespace Tizen.Applications private void ChangeCurrentCultureInfo(string locale) { - string languageCode = string.Empty; - string localeCode = string.Empty; + ULocale pLocale = new ULocale(locale); CultureInfo currentCultureInfo = null; - if (locale.Contains(".")) + try { - locale = locale.Substring(0, locale.IndexOf(".")); + currentCultureInfo = new CultureInfo(pLocale.Locale.Replace("_", "-")); } + catch (CultureNotFoundException) + { + currentCultureInfo = GetFallbackCultureInfo(pLocale); + } + + CultureInfo.CurrentCulture = currentCultureInfo; + } + + private CultureInfo GetCultureInfo(string locale) + { + CultureInfo cultureInfo = null; - if (locale.Contains("_")) + try { - locale = locale.Replace("_", "-"); + cultureInfo = new CultureInfo(locale); } + catch (CultureNotFoundException) + { + return null; + } + + return cultureInfo; + } - var dashIndex = locale.IndexOf("-", StringComparison.Ordinal); - if (dashIndex > 0) + private CultureInfo GetFallbackCultureInfo(ULocale uLocale) + { + string locale = string.Empty; + CultureInfo fallbackCultureInfo = null; + + if (uLocale.Script != null && uLocale.Country != null) { - var parts = locale.Split('-'); - languageCode = parts[0]; - localeCode = parts[1]; + locale = uLocale.Language + "-" + uLocale.Script + "-" + uLocale.Country; + fallbackCultureInfo = GetCultureInfo(locale); } - else + + if (fallbackCultureInfo == null && uLocale.Script != null) { - languageCode = locale; - localeCode = ""; + locale = uLocale.Language + "-" + uLocale.Script; + fallbackCultureInfo = GetCultureInfo(locale); } - foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures)) + if (fallbackCultureInfo == null && uLocale.Country != null) { - if (ci.TwoLetterISOLanguageName == languageCode) - { - if (localeCode == "") - { - if (ci.Name == languageCode) - { - currentCultureInfo = new CultureInfo(ci.Name); - break; - } - } - else - { - if (ci.Name.Contains(localeCode.ToUpper())) - { - currentCultureInfo = new CultureInfo(ci.Name); - break; - } - } - } + locale = uLocale.Language + "-" + uLocale.Country; + fallbackCultureInfo = GetCultureInfo(locale); } - if (currentCultureInfo == null) + if (fallbackCultureInfo == null) { try { - currentCultureInfo = new CultureInfo(languageCode); + fallbackCultureInfo = new CultureInfo(uLocale.Language); } catch (CultureNotFoundException) { - currentCultureInfo = new CultureInfo("en"); + fallbackCultureInfo = new CultureInfo("en"); } } - CultureInfo.CurrentCulture = currentCultureInfo; + return fallbackCultureInfo; + } + } + + internal class ULocale + { + private const int ICU_ULOC_FULLNAME_CAPACITY = 157; + private const int ICU_ULOC_LANG_CAPACITY = 12; + private const int ICU_ULOC_SCRIPT_CAPACITY = 6; + private const int ICU_ULOC_COUNTRY_CAPACITY = 4; + private const int ICU_ULOC_VARIANT_CAPACITY = ICU_ULOC_FULLNAME_CAPACITY; + private const int ICU_U_ZERO_ERROR = 0; + + internal ULocale(string locale) + { + Locale = Canonicalize(locale); + Language = GetLanguage(Locale); + Script = GetScript(Locale); + Country = GetCountry(Locale); + Variant = GetVariant(Locale); + } + + internal string Locale { get; private set; } + internal string Language { get; private set; } + internal string Script { get; private set; } + internal string Country { get; private set; } + internal string Variant { get; private set; } + + private string Canonicalize(string localeName) + { + int err = ICU_U_ZERO_ERROR; + + // Get the locale name from ICU + StringBuilder sb = new StringBuilder(ICU_ULOC_FULLNAME_CAPACITY); + if (Interop.Icu.Canonicalize(localeName, sb, sb.Capacity, out err) <= 0) + { + return null; + } + + return sb.ToString(); + } + + private string GetLanguage(string locale) + { + int err = ICU_U_ZERO_ERROR; + + // Get the language name from ICU + StringBuilder sb = new StringBuilder(ICU_ULOC_LANG_CAPACITY); + if (Interop.Icu.GetLanguage(locale, sb, sb.Capacity, out err) <= 0) + { + return null; + } + + return sb.ToString(); + } + + private string GetScript(string locale) + { + int err = ICU_U_ZERO_ERROR; + + // Get the script name from ICU + StringBuilder sb = new StringBuilder(ICU_ULOC_SCRIPT_CAPACITY); + if (Interop.Icu.GetScript(locale, sb, sb.Capacity, out err) <= 0) + { + return null; + } + + return sb.ToString(); + } + + private string GetCountry(string locale) + { + int err = ICU_U_ZERO_ERROR; + + // Get the country name from ICU + StringBuilder sb = new StringBuilder(ICU_ULOC_SCRIPT_CAPACITY); + if (Interop.Icu.GetCountry(locale, sb, sb.Capacity, out err) <= 0) + { + return null; + } + + return sb.ToString(); + } + + private string GetVariant(string locale) + { + int err = ICU_U_ZERO_ERROR; + + // Get the country name from ICU + StringBuilder sb = new StringBuilder(ICU_ULOC_VARIANT_CAPACITY); + if (Interop.Icu.GetVariant(locale, sb, sb.Capacity, out err) <= 0) + { + return null; + } + + return sb.ToString(); } } }