From 15cd1266a9421225db61d9bc4ea40ae62a5e18a0 Mon Sep 17 00:00:00 2001 From: Noel Chou Date: Tue, 4 Nov 2025 14:26:15 -0500 Subject: [PATCH] BL-15436 another fix for chinese name handling --- CHANGELOG.md | 1 + SIL.WritingSystems/IetfLanguageTag.cs | 60 +++++++++++++-------------- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a89eaa01..c259b68e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - [SIL.DictionaryServices] Fix memory leak in LiftWriter - [SIL.WritingSystems] Fix IetfLanguageTag.GetGeneralCode to handle cases when zh-CN or zh-TW is a prefix and not the whole string. +- [SIL.WritingSystems] More fixes to consistently use 繁体中文 and 简体中文 for Traditional and Simplified Chinese native language names, and Chinese (Traditional) and Chinese (Simplified) for their English names. - [SIL.Windows.Forms] Prevent BetterLabel from responding to OnTextChanged when it has been disposed. - [SIL.Windows.Forms] Prevent ContributorsListControl.GetContributionFromRow from throwing an exception when the DataGridView has no valid rows selected. diff --git a/SIL.WritingSystems/IetfLanguageTag.cs b/SIL.WritingSystems/IetfLanguageTag.cs index b66650dba..2a424eb10 100644 --- a/SIL.WritingSystems/IetfLanguageTag.cs +++ b/SIL.WritingSystems/IetfLanguageTag.cs @@ -1290,10 +1290,12 @@ private static string GetLocalizedLanguageNameFromIcu(string languageTag, string /// Get the language name in the language of uiLanguageTag if possible /// (and if uiLanguageTag is provided). /// Otherwise, get the name in the language itself if possible (autonym). - /// It that doesn't work, return the English name. + /// If that doesn't work, return the English name. /// If we don't know even that, return the tag as the name. /// Note, in most cases, we do not get the language name in uiLanguage unless /// using ICU or uiLanguage happens to match the system CurrentCulture. + /// For "zh" and "prs", which require special handling for the specific names we want, + /// we only return the autonym or, if the UI language is English, the English name. /// [PublicAPI] public static string GetLocalizedLanguageName(string languageTag, string uiLanguageTag) @@ -1304,21 +1306,24 @@ public static string GetLocalizedLanguageName(string languageTag, string uiLangu var generalCode = GetGeneralCode(languageTag); var uiLanguageCode = GetLanguagePart(uiLanguageTag); - if (generalCode == ChineseSimplifiedTag && uiLanguageCode == "en") + if (generalCode == ChineseSimplifiedTag) { - // We also use this as the "English Subtitle" in GetNativeLanguageNameWithEnglishSubtitle. Not sure if - // it really matters here, but the ICU-supplied name (e.g., used on Linux), and the EnglishName and + // We also use this as the "English Subtitle" in GetNativeLanguageNameWithEnglishSubtitle. + // The ICU-supplied name (e.g., used on Linux), and the EnglishName and // DisplayName supplied via the Windows CultureInfo are all subtly different in // unhelpful ways: // ICU: Chinese (China) // DisplayName: Chinese (Simplified, PRC) or Chinese (Simplified, Mainland China) or Chinese (China) // EnglishName: Chinese (Simplified, China) or Chinese (Simplified, Mainland China) or Chinese (China) - - return kSimplifiedChineseNameInEnglish; + if (uiLanguageCode == "en") + return kSimplifiedChineseNameInEnglish; + return kSimplifiedChineseAutonym; } - else if (generalCode == ChineseTraditionalTag && uiLanguageCode == "en") + if (generalCode == ChineseTraditionalTag) { - return kTraditionalChineseNameInEnglish; + if (uiLanguageCode == "en") + return kTraditionalChineseNameInEnglish; + return kTraditionalChineseAutonym; } // Starting some time around Sept 2025, Windows started returning the "fa" culture @@ -1360,11 +1365,7 @@ public static string GetLocalizedLanguageName(string languageTag, string uiLangu langName = ci.DisplayName; if (uiLanguageCode != "en") { - if ( - langName == ci.EnglishName - || generalCode == ChineseSimplifiedTag - || generalCode == ChineseTraditionalTag - ) + if (langName == ci.EnglishName) langName = FixBotchedNativeName(ci.NativeName); } if (IsNullOrWhiteSpace(langName)) @@ -1424,6 +1425,14 @@ public static string GetNativeLanguageNameWithEnglishSubtitle(string code) // englishNameSuffix is always an empty string if we don't need it. string englishNameSuffix = Empty; + if (generalCode == ChineseSimplifiedTag) + { + return $"{kSimplifiedChineseAutonym} ({kSimplifiedChineseNameInEnglish})"; + } + if (generalCode == ChineseTraditionalTag) + { + return $"{kTraditionalChineseAutonym} ({kTraditionalChineseNameInEnglish})"; + } // Starting some time around Sept 2025, Windows started returning the "fa" culture // for CultureInfo.GetCultureInfo("prs"). We actually want to return Dari in that case. if (generalCode == "prs") @@ -1437,16 +1446,13 @@ public static string GetNativeLanguageNameWithEnglishSubtitle(string code) if (IsNullOrWhiteSpace(nativeName)) nativeName = code; - if (ci.Name != ChineseSimplifiedTag && ci.Name != ChineseTraditionalTag) - { - // Remove any country (or script?) names. - var idxCountry = englishNameSuffix.LastIndexOf(" (", StringComparison.Ordinal); - if (englishNameSuffix.Length > 0 && idxCountry > 0) - englishNameSuffix = englishNameSuffix.Substring(0, idxCountry) + ")"; - idxCountry = nativeName.IndexOf(" (", StringComparison.Ordinal); - if (idxCountry > 0) - nativeName = nativeName.Substring(0, idxCountry); - } + // Remove any country (or script?) names. + var idxCountry = englishNameSuffix.LastIndexOf(" (", StringComparison.Ordinal); + if (englishNameSuffix.Length > 0 && idxCountry > 0) + englishNameSuffix = englishNameSuffix.Substring(0, idxCountry) + ")"; + idxCountry = nativeName.IndexOf(" (", StringComparison.Ordinal); + if (idxCountry > 0) + nativeName = nativeName.Substring(0, idxCountry); langName = nativeName + englishNameSuffix; if (!ci.IsUnknownCulture()) { @@ -1594,14 +1600,6 @@ private static string FixBotchedNativeName(string name) // Incorrect capitalization on older Windows OS versions. case "Português": return "português"; - case "中文(中国)": - case "中文(中国)": - return kSimplifiedChineseAutonym; - case "中文(台灣)": - case "中文(台灣)": - case "中文(台湾)": - case "中文(台湾)": - return kTraditionalChineseAutonym; default: return name; }