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