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