1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_i18nisolang.hxx"
26 #include <sal/config.h>
27 #include <rtl/ustring.hxx>
28 #include <rtl/string.hxx>
29 #include <com/sun/star/i18n/ScriptType.hpp>
30
31 #include "i18npool/mslangid.hxx"
32
33
34 LanguageType MsLangId::nConfiguredSystemLanguage = LANGUAGE_SYSTEM;
35 LanguageType MsLangId::nConfiguredSystemUILanguage = LANGUAGE_SYSTEM;
36
37 LanguageType MsLangId::nConfiguredWesternFallback = LANGUAGE_SYSTEM;
38 LanguageType MsLangId::nConfiguredAsianFallback = LANGUAGE_SYSTEM;
39 LanguageType MsLangId::nConfiguredComplexFallback = LANGUAGE_SYSTEM;
40
41 // static
setConfiguredSystemLanguage(LanguageType nLang)42 void MsLangId::setConfiguredSystemLanguage( LanguageType nLang )
43 {
44 nConfiguredSystemLanguage = nLang;
45 }
46
47
48 // static
setConfiguredSystemUILanguage(LanguageType nLang)49 void MsLangId::setConfiguredSystemUILanguage( LanguageType nLang )
50 {
51 nConfiguredSystemUILanguage = nLang;
52 }
53
54 // static
setConfiguredWesternFallback(LanguageType nLang)55 void MsLangId::setConfiguredWesternFallback( LanguageType nLang )
56 {
57 nConfiguredWesternFallback = nLang;
58 }
59
60 // static
setConfiguredAsianFallback(LanguageType nLang)61 void MsLangId::setConfiguredAsianFallback( LanguageType nLang )
62 {
63 nConfiguredAsianFallback = nLang;
64 }
65
66 // static
setConfiguredComplexFallback(LanguageType nLang)67 void MsLangId::setConfiguredComplexFallback( LanguageType nLang )
68 {
69 nConfiguredComplexFallback = nLang;
70 }
71
72 // static
simplifySystemLanguages(LanguageType nLang)73 inline LanguageType MsLangId::simplifySystemLanguages( LanguageType nLang )
74 {
75 switch (nLang)
76 {
77 case LANGUAGE_PROCESS_OR_USER_DEFAULT :
78 case LANGUAGE_SYSTEM_DEFAULT :
79 case LANGUAGE_SYSTEM :
80 nLang = LANGUAGE_SYSTEM;
81 break;
82 default:
83 ; // nothing
84 }
85 return nLang;
86 }
87
88
89 // static
getRealLanguageWithoutConfig(LanguageType nLang)90 LanguageType MsLangId::getRealLanguageWithoutConfig( LanguageType nLang )
91 {
92 switch (simplifySystemLanguages( nLang))
93 {
94 case LANGUAGE_SYSTEM :
95 nLang = getSystemLanguage();
96 break;
97 case LANGUAGE_NONE :
98 nLang = getSystemUILanguage();
99 break;
100 default:
101 /* TODO: would this be useful here? */
102 //nLang = MsLangId::getReplacementForObsoleteLanguage( nLang);
103 ; // nothing
104 }
105 if (nLang == LANGUAGE_DONTKNOW)
106 nLang = LANGUAGE_ENGLISH_US;
107 return nLang;
108 }
109
110
111 // static
getRealLanguage(LanguageType nLang)112 LanguageType MsLangId::getRealLanguage( LanguageType nLang )
113 {
114 switch (simplifySystemLanguages( nLang))
115 {
116 case LANGUAGE_SYSTEM :
117 if (nConfiguredSystemLanguage == LANGUAGE_SYSTEM)
118 nLang = getSystemLanguage();
119 else
120 nLang = nConfiguredSystemLanguage;
121 break;
122 case LANGUAGE_NONE :
123 if (nConfiguredSystemUILanguage == LANGUAGE_SYSTEM)
124 nLang = getSystemUILanguage();
125 else
126 nLang = nConfiguredSystemUILanguage;
127 break;
128 default:
129 /* TODO: would this be useful here? */
130 //nLang = MsLangId::getReplacementForObsoleteLanguage( nLang);
131 ; // nothing
132 }
133 if (nLang == LANGUAGE_DONTKNOW)
134 nLang = LANGUAGE_ENGLISH_US;
135 return nLang;
136 }
137
138
139 // static
resolveSystemLanguageByScriptType(LanguageType nLang,sal_Int16 nType)140 LanguageType MsLangId::resolveSystemLanguageByScriptType( LanguageType nLang, sal_Int16 nType )
141 {
142 if (nLang == LANGUAGE_NONE)
143 return nLang;
144
145 nLang = getRealLanguage(nLang);
146 if (nType != ::com::sun::star::i18n::ScriptType::WEAK && getScriptType(nLang) != nType)
147 {
148 switch(nType)
149 {
150 case ::com::sun::star::i18n::ScriptType::ASIAN:
151 if (nConfiguredAsianFallback == LANGUAGE_SYSTEM)
152 nLang = LANGUAGE_CHINESE_SIMPLIFIED;
153 else
154 nLang = nConfiguredAsianFallback;
155 break;
156 case ::com::sun::star::i18n::ScriptType::COMPLEX:
157 if (nConfiguredComplexFallback == LANGUAGE_SYSTEM)
158 nLang = LANGUAGE_HINDI;
159 else
160 nLang = nConfiguredComplexFallback;
161 break;
162 default:
163 if (nConfiguredWesternFallback == LANGUAGE_SYSTEM)
164 nLang = LANGUAGE_ENGLISH_US;
165 else
166 nLang = nConfiguredWesternFallback;
167 break;
168 }
169 }
170 return nLang;
171 }
172
173 // static
convertLanguageToLocale(LanguageType nLang,::com::sun::star::lang::Locale & rLocale)174 void MsLangId::convertLanguageToLocale( LanguageType nLang,
175 ::com::sun::star::lang::Locale & rLocale )
176 {
177 if (rLocale.Variant.getLength())
178 rLocale.Variant = rtl::OUString();
179 convertLanguageToIsoNames( nLang, rLocale.Language, rLocale.Country);
180 }
181
182
183 // static
convertLanguageToLocale(LanguageType nLang,bool bResolveSystem)184 ::com::sun::star::lang::Locale MsLangId::convertLanguageToLocale(
185 LanguageType nLang, bool bResolveSystem )
186 {
187 ::com::sun::star::lang::Locale aLocale;
188 if (!bResolveSystem && simplifySystemLanguages( nLang) == LANGUAGE_SYSTEM)
189 ; // nothing => empty locale
190 else
191 {
192 // Still resolve LANGUAGE_DONTKNOW if resolving is not requested,
193 // but not LANGUAGE_NONE or others.
194 if (bResolveSystem || nLang == LANGUAGE_DONTKNOW)
195 nLang = MsLangId::getRealLanguage( nLang);
196 convertLanguageToLocale( nLang, aLocale);
197 }
198 return aLocale;
199 }
200
201
202 // static
convertLocaleToLanguage(const::com::sun::star::lang::Locale & rLocale)203 LanguageType MsLangId::convertLocaleToLanguage(
204 const ::com::sun::star::lang::Locale& rLocale )
205 {
206 // empty language => LANGUAGE_SYSTEM
207 if (rLocale.Language.getLength() == 0)
208 return LANGUAGE_SYSTEM;
209
210 LanguageType nRet = convertIsoNamesToLanguage( rLocale.Language,
211 rLocale.Country);
212 if (nRet == LANGUAGE_DONTKNOW)
213 nRet = LANGUAGE_SYSTEM;
214
215 return nRet;
216 }
217
218
219 // static
convertLocaleToLanguageWithFallback(const::com::sun::star::lang::Locale & rLocale)220 LanguageType MsLangId::convertLocaleToLanguageWithFallback(
221 const ::com::sun::star::lang::Locale & rLocale )
222 {
223 // empty language => LANGUAGE_SYSTEM
224 if (rLocale.Language.getLength() == 0)
225 return lookupFallbackLanguage( LANGUAGE_SYSTEM);
226
227 return lookupFallbackLanguage( rLocale);
228 }
229
230
231 // static
convertLanguageToLocaleWithFallback(LanguageType nLang)232 ::com::sun::star::lang::Locale MsLangId::convertLanguageToLocaleWithFallback(
233 LanguageType nLang )
234 {
235 return lookupFallbackLocale( MsLangId::getRealLanguage( nLang));
236 }
237
238
239 // static
getFallbackLocale(const::com::sun::star::lang::Locale & rLocale)240 ::com::sun::star::lang::Locale MsLangId::getFallbackLocale(
241 const ::com::sun::star::lang::Locale & rLocale )
242 {
243 // empty language => LANGUAGE_SYSTEM
244 if (rLocale.Language.getLength() == 0)
245 return convertLanguageToLocaleWithFallback( LANGUAGE_SYSTEM);
246
247 return lookupFallbackLocale( rLocale);
248 }
249
250
251 // static
getFallbackLanguage(LanguageType nLang)252 LanguageType MsLangId::getFallbackLanguage( LanguageType nLang )
253 {
254 return lookupFallbackLanguage( MsLangId::getRealLanguage( nLang));
255 }
256
257
258 // static
isRightToLeft(LanguageType nLang)259 bool MsLangId::isRightToLeft( LanguageType nLang )
260 {
261 switch( nLang & LANGUAGE_MASK_PRIMARY )
262 {
263 case LANGUAGE_ARABIC_SAUDI_ARABIA & LANGUAGE_MASK_PRIMARY :
264 case LANGUAGE_HEBREW & LANGUAGE_MASK_PRIMARY :
265 case LANGUAGE_YIDDISH & LANGUAGE_MASK_PRIMARY :
266 case LANGUAGE_URDU & LANGUAGE_MASK_PRIMARY :
267 case LANGUAGE_FARSI & LANGUAGE_MASK_PRIMARY :
268 case LANGUAGE_KASHMIRI & LANGUAGE_MASK_PRIMARY :
269 case LANGUAGE_SINDHI & LANGUAGE_MASK_PRIMARY :
270 case LANGUAGE_UIGHUR_CHINA & LANGUAGE_MASK_PRIMARY :
271 return true;
272
273 default:
274 break;
275 }
276 return false;
277 }
278
279
280 // static
hasForbiddenCharacters(LanguageType nLang)281 bool MsLangId::hasForbiddenCharacters( LanguageType nLang )
282 {
283 switch (nLang & LANGUAGE_MASK_PRIMARY)
284 {
285 case LANGUAGE_CHINESE & LANGUAGE_MASK_PRIMARY:
286 case LANGUAGE_JAPANESE & LANGUAGE_MASK_PRIMARY:
287 case LANGUAGE_KOREAN & LANGUAGE_MASK_PRIMARY:
288 return true;
289 default:
290 break;
291 }
292 return false;
293 }
294
295
296 // static
needsSequenceChecking(LanguageType nLang)297 bool MsLangId::needsSequenceChecking( LanguageType nLang )
298 {
299 switch (nLang & LANGUAGE_MASK_PRIMARY)
300 {
301 case LANGUAGE_BURMESE & LANGUAGE_MASK_PRIMARY:
302 case LANGUAGE_KHMER & LANGUAGE_MASK_PRIMARY:
303 case LANGUAGE_LAO & LANGUAGE_MASK_PRIMARY:
304 case LANGUAGE_THAI & LANGUAGE_MASK_PRIMARY:
305 return true;
306 default:
307 break;
308 }
309 return false;
310 }
311
312
313 // static
getScriptType(LanguageType nLang)314 sal_Int16 MsLangId::getScriptType( LanguageType nLang )
315 {
316 sal_Int16 nScript;
317 switch( nLang )
318 {
319 // CJK
320 // all LANGUAGE_CHINESE_... are caught below
321 case LANGUAGE_JAPANESE:
322 case LANGUAGE_KOREAN:
323 case LANGUAGE_KOREAN_JOHAB:
324 case LANGUAGE_USER_KOREAN_NORTH:
325 nScript = ::com::sun::star::i18n::ScriptType::ASIAN;
326 break;
327
328 // CTL
329 // all LANGUAGE_ARABIC_... are caught below
330 case LANGUAGE_AMHARIC_ETHIOPIA:
331 case LANGUAGE_ASSAMESE:
332 case LANGUAGE_BENGALI:
333 case LANGUAGE_BENGALI_BANGLADESH:
334 case LANGUAGE_BURMESE:
335 case LANGUAGE_FARSI:
336 case LANGUAGE_HEBREW:
337 case LANGUAGE_YIDDISH:
338 case LANGUAGE_USER_YIDDISH_US:
339 case LANGUAGE_MARATHI:
340 case LANGUAGE_PUNJABI:
341 case LANGUAGE_GUJARATI:
342 case LANGUAGE_HINDI:
343 case LANGUAGE_KANNADA:
344 case LANGUAGE_KASHMIRI:
345 case LANGUAGE_KASHMIRI_INDIA:
346 case LANGUAGE_KHMER:
347 case LANGUAGE_LAO:
348 case LANGUAGE_MALAYALAM:
349 case LANGUAGE_MANIPURI:
350 case LANGUAGE_MONGOLIAN_MONGOLIAN:
351 case LANGUAGE_NEPALI:
352 case LANGUAGE_NEPALI_INDIA:
353 case LANGUAGE_ORIYA:
354 case LANGUAGE_SANSKRIT:
355 case LANGUAGE_SINDHI:
356 case LANGUAGE_SINDHI_PAKISTAN:
357 case LANGUAGE_SINHALESE_SRI_LANKA:
358 case LANGUAGE_SYRIAC:
359 case LANGUAGE_TAMIL:
360 case LANGUAGE_TELUGU:
361 case LANGUAGE_THAI:
362 case LANGUAGE_TIBETAN:
363 case LANGUAGE_DZONGKHA:
364 case LANGUAGE_URDU:
365 case LANGUAGE_URDU_PAKISTAN:
366 case LANGUAGE_URDU_INDIA:
367 case LANGUAGE_USER_KURDISH_IRAQ:
368 case LANGUAGE_USER_KURDISH_IRAN:
369 case LANGUAGE_DHIVEHI:
370 case LANGUAGE_USER_BODO_INDIA:
371 case LANGUAGE_USER_DOGRI_INDIA:
372 case LANGUAGE_USER_MAITHILI_INDIA:
373 case LANGUAGE_UIGHUR_CHINA:
374 case LANGUAGE_USER_LIMBU:
375 nScript = ::com::sun::star::i18n::ScriptType::COMPLEX;
376 break;
377
378 // currently not knowing scripttype - defaulted to LATIN:
379 /*
380 #define LANGUAGE_ARMENIAN 0x042B
381 #define LANGUAGE_INDONESIAN 0x0421
382 #define LANGUAGE_KAZAK 0x043F
383 #define LANGUAGE_KONKANI 0x0457
384 #define LANGUAGE_MACEDONIAN 0x042F
385 #define LANGUAGE_TATAR 0x0444
386 */
387
388 default:
389 switch ( nLang & LANGUAGE_MASK_PRIMARY )
390 {
391 // CJK catcher
392 case LANGUAGE_CHINESE & LANGUAGE_MASK_PRIMARY:
393 nScript = ::com::sun::star::i18n::ScriptType::ASIAN;
394 break;
395 // CTL catcher
396 case LANGUAGE_ARABIC_SAUDI_ARABIA & LANGUAGE_MASK_PRIMARY:
397 nScript = ::com::sun::star::i18n::ScriptType::COMPLEX;
398 break;
399 // Western (actually not necessarily Latin but also Cyrillic, for example)
400 default:
401 nScript = ::com::sun::star::i18n::ScriptType::LATIN;
402 }
403 break;
404 }
405 return nScript;
406 }
407
408
409 // static
getReplacementForObsoleteLanguage(LanguageType nLang)410 LanguageType MsLangId::getReplacementForObsoleteLanguage( LanguageType nLang )
411 {
412 switch (nLang)
413 {
414 default:
415 break; // nothing
416 case LANGUAGE_OBSOLETE_USER_LATIN:
417 nLang = LANGUAGE_LATIN;
418 break;
419 case LANGUAGE_OBSOLETE_USER_MAORI:
420 nLang = LANGUAGE_MAORI_NEW_ZEALAND;
421 break;
422 case LANGUAGE_OBSOLETE_USER_KINYARWANDA:
423 nLang = LANGUAGE_KINYARWANDA_RWANDA;
424 break;
425 case LANGUAGE_OBSOLETE_USER_UPPER_SORBIAN:
426 nLang = LANGUAGE_UPPER_SORBIAN_GERMANY;
427 break;
428 case LANGUAGE_OBSOLETE_USER_LOWER_SORBIAN:
429 nLang = LANGUAGE_LOWER_SORBIAN_GERMANY;
430 break;
431 case LANGUAGE_OBSOLETE_USER_OCCITAN:
432 nLang = LANGUAGE_OCCITAN_FRANCE;
433 break;
434 case LANGUAGE_OBSOLETE_USER_BRETON:
435 nLang = LANGUAGE_BRETON_FRANCE;
436 break;
437 case LANGUAGE_OBSOLETE_USER_KALAALLISUT:
438 nLang = LANGUAGE_KALAALLISUT_GREENLAND;
439 break;
440 case LANGUAGE_OBSOLETE_USER_LUXEMBOURGISH:
441 nLang = LANGUAGE_LUXEMBOURGISH_LUXEMBOURG;
442 break;
443
444 // The following are not strictly obsolete but should be mapped to a
445 // replacement locale when encountered.
446
447 // no_NO is an alias for nb_NO
448 case LANGUAGE_NORWEGIAN:
449 nLang = LANGUAGE_NORWEGIAN_BOKMAL;
450 break;
451
452 // #i94435# A Spanish variant that differs only in collation details we
453 // do not support.
454 case LANGUAGE_SPANISH_DATED:
455 nLang = LANGUAGE_SPANISH_MODERN;
456 break;
457
458 // Do not use ca-XV, ca-XR for document content.
459 /* TODO: remove in case we implement BCP47 language tags. */
460 case LANGUAGE_USER_CATALAN_VALENCIAN:
461 case LANGUAGE_USER_CATALAN_VALENCIAN_RACV:
462 nLang = LANGUAGE_CATALAN;
463 break;
464 }
465 return nLang;
466 }
467