| 1 | // Copyright (C) 2016 The Qt Company Ltd. |
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 |
| 3 | |
| 4 | #include "translator.h" |
| 5 | |
| 6 | #include <QtCore/QByteArray> |
| 7 | #include <QtCore/QDebug> |
| 8 | #include <QtCore/QDir> |
| 9 | #include <QtCore/QFile> |
| 10 | #include <QtCore/QFileInfo> |
| 11 | #include <QtCore/QMap> |
| 12 | |
| 13 | #include <private/qtranslator_p.h> |
| 14 | |
| 15 | QT_BEGIN_NAMESPACE |
| 16 | |
| 17 | static const uchar englishStyleRules[] = |
| 18 | { Q_EQ, 1 }; |
| 19 | static const uchar frenchStyleRules[] = |
| 20 | { Q_LEQ, 1 }; |
| 21 | static const uchar latvianRules[] = |
| 22 | { Q_MOD_10 | Q_EQ, 1, Q_AND, Q_MOD_100 | Q_NEQ, 11, Q_NEWRULE, |
| 23 | Q_NEQ, 0 }; |
| 24 | static const uchar icelandicRules[] = |
| 25 | { Q_MOD_10 | Q_EQ, 1, Q_AND, Q_MOD_100 | Q_NEQ, 11 }; |
| 26 | static const uchar irishStyleRules[] = |
| 27 | { Q_EQ, 1, Q_NEWRULE, |
| 28 | Q_EQ, 2 }; |
| 29 | static const uchar gaelicStyleRules[] = |
| 30 | { Q_EQ, 1, Q_OR, Q_EQ, 11, Q_NEWRULE, |
| 31 | Q_EQ, 2, Q_OR, Q_EQ, 12, Q_NEWRULE, |
| 32 | Q_BETWEEN, 3, 19 }; |
| 33 | static const uchar slovakStyleRules[] = |
| 34 | { Q_EQ, 1, Q_NEWRULE, |
| 35 | Q_BETWEEN, 2, 4 }; |
| 36 | static const uchar macedonianRules[] = |
| 37 | { Q_MOD_10 | Q_EQ, 1, Q_NEWRULE, |
| 38 | Q_MOD_10 | Q_EQ, 2 }; |
| 39 | static const uchar lithuanianRules[] = |
| 40 | { Q_MOD_10 | Q_EQ, 1, Q_AND, Q_MOD_100 | Q_NEQ, 11, Q_NEWRULE, |
| 41 | Q_MOD_10 | Q_NEQ, 0, Q_AND, Q_MOD_100 | Q_NOT_BETWEEN, 10, 19 }; |
| 42 | static const uchar russianStyleRules[] = |
| 43 | { Q_MOD_10 | Q_EQ, 1, Q_AND, Q_MOD_100 | Q_NEQ, 11, Q_NEWRULE, |
| 44 | Q_MOD_10 | Q_BETWEEN, 2, 4, Q_AND, Q_MOD_100 | Q_NOT_BETWEEN, 10, 19 }; |
| 45 | static const uchar polishRules[] = |
| 46 | { Q_EQ, 1, Q_NEWRULE, |
| 47 | Q_MOD_10 | Q_BETWEEN, 2, 4, Q_AND, Q_MOD_100 | Q_NOT_BETWEEN, 10, 19 }; |
| 48 | static const uchar romanianRules[] = |
| 49 | { Q_EQ, 1, Q_NEWRULE, |
| 50 | Q_EQ, 0, Q_OR, Q_MOD_100 | Q_BETWEEN, 1, 19 }; |
| 51 | static const uchar slovenianRules[] = |
| 52 | { Q_MOD_100 | Q_EQ, 1, Q_NEWRULE, |
| 53 | Q_MOD_100 | Q_EQ, 2, Q_NEWRULE, |
| 54 | Q_MOD_100 | Q_BETWEEN, 3, 4 }; |
| 55 | static const uchar malteseRules[] = |
| 56 | { Q_EQ, 1, Q_NEWRULE, |
| 57 | Q_EQ, 0, Q_OR, Q_MOD_100 | Q_BETWEEN, 1, 10, Q_NEWRULE, |
| 58 | Q_MOD_100 | Q_BETWEEN, 11, 19 }; |
| 59 | static const uchar welshRules[] = |
| 60 | { Q_EQ, 0, Q_NEWRULE, |
| 61 | Q_EQ, 1, Q_NEWRULE, |
| 62 | Q_BETWEEN, 2, 5, Q_NEWRULE, |
| 63 | Q_EQ, 6 }; |
| 64 | static const uchar arabicRules[] = |
| 65 | { Q_EQ, 0, Q_NEWRULE, |
| 66 | Q_EQ, 1, Q_NEWRULE, |
| 67 | Q_EQ, 2, Q_NEWRULE, |
| 68 | Q_MOD_100 | Q_BETWEEN, 3, 10, Q_NEWRULE, |
| 69 | Q_MOD_100 | Q_GEQ, 11 }; |
| 70 | static const uchar tagalogRules[] = |
| 71 | { Q_LEQ, 1, Q_NEWRULE, |
| 72 | Q_MOD_10 | Q_EQ, 4, Q_OR, Q_MOD_10 | Q_EQ, 6, Q_OR, Q_MOD_10 | Q_EQ, 9 }; |
| 73 | |
| 74 | static const char * const japaneseStyleForms[] = { "Universal Form" , 0 }; |
| 75 | static const char * const englishStyleForms[] = { "Singular" , "Plural" , 0 }; |
| 76 | static const char * const frenchStyleForms[] = { "Singular" , "Plural" , 0 }; |
| 77 | static const char * const icelandicForms[] = { "Singular" , "Plural" , 0 }; |
| 78 | static const char * const latvianForms[] = { "Singular" , "Plural" , "Nullar" , 0 }; |
| 79 | static const char * const irishStyleForms[] = { "Singular" , "Dual" , "Plural" , 0 }; |
| 80 | // Gaelic uses the grammatical Singular for the Plural cardinality, |
| 81 | // so using the Latin terms is expected to cause confusion. |
| 82 | static const char * const gaelicStyleForms[] = { "1/11" , "2/12" , "Few" , "Many" , 0 }; |
| 83 | static const char * const slovakStyleForms[] = { "Singular" , "Paucal" , "Plural" , 0 }; |
| 84 | static const char * const macedonianForms[] = { "Singular" , "Dual" , "Plural" , 0 }; |
| 85 | static const char * const lithuanianForms[] = { "Singular" , "Paucal" , "Plural" , 0 }; |
| 86 | static const char * const russianStyleForms[] = { "Singular" , "Dual" , "Plural" , 0 }; |
| 87 | static const char * const polishForms[] = { "Singular" , "Paucal" , "Plural" , 0 }; |
| 88 | static const char * const romanianForms[] = { "Singular" , "Paucal" , "Plural" , 0 }; |
| 89 | static const char * const slovenianForms[] = { "Singular" , "Dual" , "Trial" , "Plural" , 0 }; |
| 90 | static const char * const malteseForms[] = |
| 91 | { "Singular" , "Paucal" , "Greater Paucal" , "Plural" , 0 }; |
| 92 | static const char * const welshForms[] = |
| 93 | { "Nullar" , "Singular" , "Dual" , "Sexal" , "Plural" , 0 }; |
| 94 | static const char * const arabicForms[] = |
| 95 | { "Nullar" , "Singular" , "Dual" , "Minority Plural" , "Plural" , "Plural (100-102, ...)" , 0 }; |
| 96 | static const char * const tagalogForms[] = |
| 97 | { "Singular" , "Plural (consonant-ended)" , "Plural (vowel-ended)" , 0 }; |
| 98 | |
| 99 | #define EOL QLocale::C |
| 100 | |
| 101 | static const QLocale::Language japaneseStyleLanguages[] = { |
| 102 | QLocale::Bislama, |
| 103 | QLocale::Burmese, |
| 104 | QLocale::Chinese, |
| 105 | QLocale::Dzongkha, |
| 106 | QLocale::Fijian, |
| 107 | QLocale::Guarani, |
| 108 | QLocale::Hungarian, |
| 109 | QLocale::Indonesian, |
| 110 | QLocale::Japanese, |
| 111 | QLocale::Javanese, |
| 112 | QLocale::Korean, |
| 113 | QLocale::Malay, |
| 114 | QLocale::NauruLanguage, |
| 115 | QLocale::Oromo, |
| 116 | QLocale::Persian, |
| 117 | QLocale::Sundanese, |
| 118 | QLocale::Tatar, |
| 119 | QLocale::Thai, |
| 120 | QLocale::Tibetan, |
| 121 | QLocale::Turkish, |
| 122 | QLocale::Vietnamese, |
| 123 | QLocale::Yoruba, |
| 124 | QLocale::Zhuang, |
| 125 | EOL |
| 126 | }; |
| 127 | |
| 128 | static const QLocale::Language englishStyleLanguages[] = { |
| 129 | QLocale::Abkhazian, |
| 130 | QLocale::Afar, |
| 131 | QLocale::Afrikaans, |
| 132 | QLocale::Albanian, |
| 133 | QLocale::Amharic, |
| 134 | QLocale::Assamese, |
| 135 | QLocale::Aymara, |
| 136 | QLocale::Azerbaijani, |
| 137 | QLocale::Bashkir, |
| 138 | QLocale::Basque, |
| 139 | QLocale::Bengali, |
| 140 | QLocale::Bulgarian, |
| 141 | QLocale::Catalan, |
| 142 | QLocale::Cornish, |
| 143 | QLocale::Corsican, |
| 144 | QLocale::Danish, |
| 145 | QLocale::Dutch, |
| 146 | QLocale::English, |
| 147 | QLocale::Esperanto, |
| 148 | QLocale::Estonian, |
| 149 | QLocale::Faroese, |
| 150 | QLocale::Finnish, |
| 151 | QLocale::Friulian, |
| 152 | QLocale::WesternFrisian, |
| 153 | QLocale::Galician, |
| 154 | QLocale::Ganda, |
| 155 | QLocale::Georgian, |
| 156 | QLocale::German, |
| 157 | QLocale::Greek, |
| 158 | QLocale::Greenlandic, |
| 159 | QLocale::Gujarati, |
| 160 | QLocale::Hausa, |
| 161 | QLocale::Hebrew, |
| 162 | QLocale::Hindi, |
| 163 | QLocale::Interlingua, |
| 164 | QLocale::Interlingue, |
| 165 | QLocale::Italian, |
| 166 | QLocale::Kannada, |
| 167 | QLocale::Kashmiri, |
| 168 | QLocale::Kazakh, |
| 169 | QLocale::Khmer, |
| 170 | QLocale::Kinyarwanda, |
| 171 | QLocale::Kirghiz, |
| 172 | QLocale::Kurdish, |
| 173 | QLocale::Lao, |
| 174 | QLocale::Latin, |
| 175 | QLocale::Lingala, |
| 176 | QLocale::Luxembourgish, |
| 177 | QLocale::Malagasy, |
| 178 | QLocale::Malayalam, |
| 179 | QLocale::Marathi, |
| 180 | QLocale::Mongolian, |
| 181 | // Missing: Nahuatl, |
| 182 | QLocale::Nepali, |
| 183 | QLocale::NorthernSotho, |
| 184 | QLocale::NorwegianBokmal, |
| 185 | QLocale::NorwegianNynorsk, |
| 186 | QLocale::Occitan, |
| 187 | QLocale::Oriya, |
| 188 | QLocale::Pashto, |
| 189 | QLocale::Portuguese, |
| 190 | QLocale::Punjabi, |
| 191 | QLocale::Quechua, |
| 192 | QLocale::Romansh, |
| 193 | QLocale::Rundi, |
| 194 | QLocale::Shona, |
| 195 | QLocale::Sindhi, |
| 196 | QLocale::Sinhala, |
| 197 | QLocale::Somali, |
| 198 | QLocale::SouthernSotho, |
| 199 | QLocale::Spanish, |
| 200 | QLocale::Swahili, |
| 201 | QLocale::Swati, |
| 202 | QLocale::Swedish, |
| 203 | QLocale::Tajik, |
| 204 | QLocale::Tamil, |
| 205 | QLocale::Telugu, |
| 206 | QLocale::Tongan, |
| 207 | QLocale::Tsonga, |
| 208 | QLocale::Tswana, |
| 209 | QLocale::Turkmen, |
| 210 | QLocale::Uigur, |
| 211 | QLocale::Urdu, |
| 212 | QLocale::Uzbek, |
| 213 | QLocale::Volapuk, |
| 214 | QLocale::Wolof, |
| 215 | QLocale::Xhosa, |
| 216 | QLocale::Yiddish, |
| 217 | QLocale::Zulu, |
| 218 | EOL |
| 219 | }; |
| 220 | static const QLocale::Language frenchStyleLanguages[] = { |
| 221 | // keep synchronized with frenchStyleCountries |
| 222 | QLocale::Armenian, |
| 223 | QLocale::Breton, |
| 224 | QLocale::French, |
| 225 | QLocale::Portuguese, |
| 226 | QLocale::Filipino, |
| 227 | QLocale::Tigrinya, |
| 228 | QLocale::Walloon, |
| 229 | EOL |
| 230 | }; |
| 231 | static const QLocale::Language latvianLanguage[] = { QLocale::Latvian, EOL }; |
| 232 | static const QLocale::Language icelandicLanguage[] = { QLocale::Icelandic, EOL }; |
| 233 | static const QLocale::Language irishStyleLanguages[] = { |
| 234 | QLocale::Divehi, |
| 235 | QLocale::Inuktitut, |
| 236 | QLocale::Inupiak, |
| 237 | QLocale::Irish, |
| 238 | QLocale::Manx, |
| 239 | QLocale::Maori, |
| 240 | QLocale::NorthernSami, |
| 241 | QLocale::Samoan, |
| 242 | QLocale::Sanskrit, |
| 243 | EOL |
| 244 | }; |
| 245 | static const QLocale::Language gaelicStyleLanguages[] = { QLocale::Gaelic, EOL }; |
| 246 | static const QLocale::Language slovakStyleLanguages[] = { QLocale::Slovak, QLocale::Czech, EOL }; |
| 247 | static const QLocale::Language macedonianLanguage[] = { QLocale::Macedonian, EOL }; |
| 248 | static const QLocale::Language lithuanianLanguage[] = { QLocale::Lithuanian, EOL }; |
| 249 | static const QLocale::Language russianStyleLanguages[] = { |
| 250 | QLocale::Bosnian, |
| 251 | QLocale::Belarusian, |
| 252 | QLocale::Croatian, |
| 253 | QLocale::Russian, |
| 254 | QLocale::Serbian, |
| 255 | QLocale::Ukrainian, |
| 256 | EOL |
| 257 | }; |
| 258 | static const QLocale::Language polishLanguage[] = { QLocale::Polish, EOL }; |
| 259 | static const QLocale::Language romanianLanguages[] = { |
| 260 | QLocale::Romanian, |
| 261 | EOL |
| 262 | }; |
| 263 | static const QLocale::Language slovenianLanguage[] = { QLocale::Slovenian, EOL }; |
| 264 | static const QLocale::Language malteseLanguage[] = { QLocale::Maltese, EOL }; |
| 265 | static const QLocale::Language welshLanguage[] = { QLocale::Welsh, EOL }; |
| 266 | static const QLocale::Language arabicLanguage[] = { QLocale::Arabic, EOL }; |
| 267 | static const QLocale::Language tagalogLanguage[] = { QLocale::Filipino, EOL }; |
| 268 | |
| 269 | static const QLocale::Territory frenchStyleCountries[] = { |
| 270 | // keep synchronized with frenchStyleLanguages |
| 271 | QLocale::AnyTerritory, |
| 272 | QLocale::AnyTerritory, |
| 273 | QLocale::AnyTerritory, |
| 274 | QLocale::Brazil, |
| 275 | QLocale::AnyTerritory, |
| 276 | QLocale::AnyTerritory, |
| 277 | QLocale::AnyTerritory |
| 278 | }; |
| 279 | struct NumerusTableEntry { |
| 280 | const uchar *rules; |
| 281 | int rulesSize; |
| 282 | const char * const *forms; |
| 283 | const QLocale::Language *languages; |
| 284 | const QLocale::Territory *countries; |
| 285 | const char * const gettextRules; |
| 286 | }; |
| 287 | |
| 288 | static const NumerusTableEntry numerusTable[] = { |
| 289 | { .rules: 0, .rulesSize: 0, .forms: japaneseStyleForms, .languages: japaneseStyleLanguages, .countries: 0, .gettextRules: "nplurals=1; plural=0;" }, |
| 290 | { .rules: englishStyleRules, .rulesSize: sizeof(englishStyleRules), .forms: englishStyleForms, .languages: englishStyleLanguages, .countries: 0, |
| 291 | .gettextRules: "nplurals=2; plural=(n != 1);" }, |
| 292 | { .rules: frenchStyleRules, .rulesSize: sizeof(frenchStyleRules), .forms: frenchStyleForms, .languages: frenchStyleLanguages, |
| 293 | .countries: frenchStyleCountries, .gettextRules: "nplurals=2; plural=(n > 1);" }, |
| 294 | { .rules: latvianRules, .rulesSize: sizeof(latvianRules), .forms: latvianForms, .languages: latvianLanguage, .countries: 0, |
| 295 | .gettextRules: "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" }, |
| 296 | { .rules: icelandicRules, .rulesSize: sizeof(icelandicRules), .forms: icelandicForms, .languages: icelandicLanguage, .countries: 0, |
| 297 | .gettextRules: "nplurals=2; plural=(n%10==1 && n%100!=11 ? 0 : 1);" }, |
| 298 | { .rules: irishStyleRules, .rulesSize: sizeof(irishStyleRules), .forms: irishStyleForms, .languages: irishStyleLanguages, .countries: 0, |
| 299 | .gettextRules: "nplurals=3; plural=(n==1 ? 0 : n==2 ? 1 : 2);" }, |
| 300 | { .rules: gaelicStyleRules, .rulesSize: sizeof(gaelicStyleRules), .forms: gaelicStyleForms, .languages: gaelicStyleLanguages, .countries: 0, |
| 301 | .gettextRules: "nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;" }, |
| 302 | { .rules: slovakStyleRules, .rulesSize: sizeof(slovakStyleRules), .forms: slovakStyleForms, .languages: slovakStyleLanguages, .countries: 0, |
| 303 | .gettextRules: "nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);" }, |
| 304 | { .rules: macedonianRules, .rulesSize: sizeof(macedonianRules), .forms: macedonianForms, .languages: macedonianLanguage, .countries: 0, |
| 305 | .gettextRules: "nplurals=3; plural=(n%100==1 ? 0 : n%100==2 ? 1 : 2);" }, |
| 306 | { .rules: lithuanianRules, .rulesSize: sizeof(lithuanianRules), .forms: lithuanianForms, .languages: lithuanianLanguage, .countries: 0, |
| 307 | .gettextRules: "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);" }, |
| 308 | { .rules: russianStyleRules, .rulesSize: sizeof(russianStyleRules), .forms: russianStyleForms, .languages: russianStyleLanguages, .countries: 0, |
| 309 | .gettextRules: "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }, |
| 310 | { .rules: polishRules, .rulesSize: sizeof(polishRules), .forms: polishForms, .languages: polishLanguage, .countries: 0, |
| 311 | .gettextRules: "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }, |
| 312 | { .rules: romanianRules, .rulesSize: sizeof(romanianRules), .forms: romanianForms, .languages: romanianLanguages, .countries: 0, |
| 313 | .gettextRules: "nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2);" }, |
| 314 | { .rules: slovenianRules, .rulesSize: sizeof(slovenianRules), .forms: slovenianForms, .languages: slovenianLanguage, .countries: 0, |
| 315 | .gettextRules: "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" }, |
| 316 | { .rules: malteseRules, .rulesSize: sizeof(malteseRules), .forms: malteseForms, .languages: malteseLanguage, .countries: 0, |
| 317 | .gettextRules: "nplurals=4; plural=(n==1 ? 0 : (n==0 || (n%100>=1 && n%100<=10)) ? 1 : (n%100>=11 && n%100<=19) ? 2 : 3);" }, |
| 318 | { .rules: welshRules, .rulesSize: sizeof(welshRules), .forms: welshForms, .languages: welshLanguage, .countries: 0, |
| 319 | .gettextRules: "nplurals=5; plural=(n==0 ? 0 : n==1 ? 1 : (n>=2 && n<=5) ? 2 : n==6 ? 3 : 4);" }, |
| 320 | { .rules: arabicRules, .rulesSize: sizeof(arabicRules), .forms: arabicForms, .languages: arabicLanguage, .countries: 0, |
| 321 | .gettextRules: "nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : (n%100>=3 && n%100<=10) ? 3 : n%100>=11 ? 4 : 5);" }, |
| 322 | { .rules: tagalogRules, .rulesSize: sizeof(tagalogRules), .forms: tagalogForms, .languages: tagalogLanguage, .countries: 0, |
| 323 | .gettextRules: "nplurals=3; plural=(n==1 ? 0 : (n%10==4 || n%10==6 || n%10== 9) ? 1 : 2);" }, |
| 324 | }; |
| 325 | |
| 326 | static const int NumerusTableSize = sizeof(numerusTable) / sizeof(numerusTable[0]); |
| 327 | |
| 328 | bool getNumerusInfo(QLocale::Language language, QLocale::Territory country, |
| 329 | QByteArray *rules, QStringList *forms, const char **gettextRules) |
| 330 | { |
| 331 | while (true) { |
| 332 | for (int i = 0; i < NumerusTableSize; ++i) { |
| 333 | const NumerusTableEntry &entry = numerusTable[i]; |
| 334 | for (int j = 0; entry.languages[j] != EOL; ++j) { |
| 335 | if (entry.languages[j] == language |
| 336 | && ((!entry.countries && country == QLocale::AnyTerritory) |
| 337 | || (entry.countries && entry.countries[j] == country))) { |
| 338 | if (rules) { |
| 339 | *rules = QByteArray::fromRawData(data: reinterpret_cast<const char *>(entry.rules), |
| 340 | size: entry.rulesSize); |
| 341 | } |
| 342 | if (gettextRules) |
| 343 | *gettextRules = entry.gettextRules; |
| 344 | if (forms) { |
| 345 | forms->clear(); |
| 346 | for (int k = 0; entry.forms[k]; ++k) |
| 347 | forms->append(t: QLatin1String(entry.forms[k])); |
| 348 | } |
| 349 | return true; |
| 350 | } |
| 351 | } |
| 352 | } |
| 353 | |
| 354 | if (country == QLocale::AnyTerritory) |
| 355 | break; |
| 356 | country = QLocale::AnyTerritory; |
| 357 | } |
| 358 | return false; |
| 359 | } |
| 360 | |
| 361 | QString getNumerusInfoString() |
| 362 | { |
| 363 | QStringList langs; |
| 364 | |
| 365 | for (int i = 0; i < NumerusTableSize; ++i) { |
| 366 | const NumerusTableEntry &entry = numerusTable[i]; |
| 367 | for (int j = 0; entry.languages[j] != EOL; ++j) { |
| 368 | QLocale loc(entry.languages[j], entry.countries ? entry.countries[j] |
| 369 | : QLocale::AnyTerritory); |
| 370 | QString lang = QLocale::languageToString(language: entry.languages[j]); |
| 371 | if (loc.language() == QLocale::C) |
| 372 | lang += QLatin1String(" (!!!)" ); |
| 373 | else if (entry.countries && entry.countries[j] != QLocale::AnyTerritory) |
| 374 | lang += QLatin1String(" (%1)" ).arg(args: QLocale::territoryToString(territory: loc.territory())); |
| 375 | else |
| 376 | lang += QLatin1String(" [%1]" ).arg(args: QLocale::territoryToString(territory: loc.territory())); |
| 377 | langs << QString::fromLatin1(ba: "%1 %2 %3\n" ).arg(a: lang, fieldWidth: -40).arg(a: loc.name(), fieldWidth: -8) |
| 378 | .arg(a: QString::fromLatin1(ba: entry.gettextRules)); |
| 379 | } |
| 380 | } |
| 381 | langs.sort(); |
| 382 | return langs.join(sep: QString()); |
| 383 | } |
| 384 | |
| 385 | QT_END_NAMESPACE |
| 386 | |