@@ -77,6 +77,14 @@ QList<QPair<QString, QString>> Localizer::parseBCP47Languages(
77
77
continue ;
78
78
}
79
79
80
+ // Chinese is often reported as `zh-Hant-HK`, and we want the middle
81
+ // section.
82
+ QString script = parts[1 ];
83
+ if (script == " Hans" || script == " Hant" ) {
84
+ codes.append (QPair<QString, QString>{parts[0 ], script});
85
+ continue ;
86
+ }
87
+
80
88
QString country = parts.last ();
81
89
if (country.length () == 2 ) {
82
90
codes.append (QPair<QString, QString>{parts[0 ], country});
@@ -96,11 +104,23 @@ QList<QPair<QString, QString>> Localizer::parseIOSLanguages(
96
104
QList<QPair<QString, QString>> codes;
97
105
98
106
for (const QString& language : languages) {
99
- // By documentation, the language code should be in the format
100
- // <language>-<script>_<country>. And we don't care about the script.
107
+ // The language code comes in the format <language>-<country> or
108
+ // <language>-<script>-<country>.
109
+ // For an iOS device set to these 6 languages: Chinese Traditional (Macao),
110
+ // Chinese Traditional, Chinese Simplified, English, Mexican Spanish,
111
+ // Spanish
112
+ // ...we get these language codes:
113
+ // [zh-Hant-MO,zh-Hant-US,zh-Hans-US,en-US,es-MX,es-US]
114
+ // iOS shows the 2 part versions for nearly all languages, and shows the
115
+ // 3 part version only when there is a script - like for Chinese variants.
116
+ // Thus, we can pull the second chunk of the locale string in all cases to
117
+ // get the translations flow required by our app. That second chunk gives
118
+ // the country for all languages except Chinese, where it gives the script -
119
+ // and in both these situations, this is what we want (script for Chinese,
120
+ // country for all others).
101
121
QString countryCode;
102
122
103
- QStringList parts = language.split (' _ ' );
123
+ QStringList parts = language.split (' - ' );
104
124
if (parts.length () > 1 ) {
105
125
countryCode = parts[1 ];
106
126
}
@@ -125,8 +145,27 @@ QString Localizer::systemLanguageCode() const {
125
145
#endif
126
146
127
147
for (const QPair<QString, QString>& language : uiLanguages) {
128
- QString selectedLanguage =
129
- findLanguageCode (language.first , language.second );
148
+ QString languagePart = language.first ;
149
+ QString localePart = language.second ;
150
+
151
+ // iOS reports Chinese as "zh-Hans" and "zh-Hant". Android reports
152
+ // them as "zh-CN" and "zh-Hans". However the app uses "zh-CN" and
153
+ // "zh-TW". We need to manually adjust these. More info:
154
+ // https://stackoverflow.com/questions/4892372/language-codes-for-simplified-chinese-and-traditional-chinese
155
+ // (For country-specific variants, it reports it as "zh-Hant-MO", etc. Since
156
+ // the app only looks at the strings before the 1st and 2nd dashes, we
157
+ // ignore the country - which is what we want to do, as we don't have
158
+ // translations for Chinese beyond simplified and traditional.)
159
+ if (languagePart == " zh" ) {
160
+ if (localePart == " Hans" ) {
161
+ localePart = " CN" ;
162
+ }
163
+ if (localePart == " Hant" ) {
164
+ localePart = " TW" ;
165
+ }
166
+ }
167
+
168
+ QString selectedLanguage = findLanguageCode (languagePart, localePart);
130
169
if (!selectedLanguage.isEmpty ()) {
131
170
return selectedLanguage;
132
171
}
0 commit comments