• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • localization
klocale_kde.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 Copyright (c) 1997,2001 Stephan Kulow <coolo@kde.org>
3 Copyright (c) 1999 Preston Brown <pbrown@kde.org>
4 Copyright (c) 1999-2002 Hans Petter Bieker <bieker@kde.org>
5 Copyright (c) 2002 Lukas Tinkl <lukas@kde.org>
6 Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
7 Copyright (C) 2009, 2010 John Layt <john@layt.net>
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
18
19 You should have received a copy of the GNU Library General Public License
20 along with this library; see the file COPYING.LIB. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA.
23*/
24
25#include "klocale_p.h"
26
27#include "config-localization.h"
28
29#include <math.h>
30#include <locale.h>
31
32#ifdef HAVE_SYS_TIME_H
33#include <sys/time.h>
34#endif
35#ifdef HAVE_TIME_H
36#include <time.h>
37#endif
38#if HAVE_LANGINFO_H
39#include <langinfo.h>
40#endif
41
42#include <QtCore/QTextCodec>
43#include <QtCore/QFile>
44#include <QtGui/QPrinter>
45#include <QtCore/QFileInfo>
46#include <QtCore/QRegExp>
47#include <QtCore/QLocale>
48#include <QtCore/QHash>
49#include <QtCore/QMutexLocker>
50#include <QtCore/QStringList>
51
52#include "kcatalog_p.h"
53#include "kglobal.h"
54#include "kstandarddirs.h"
55#include "kconfig.h"
56#include "kcomponentdata.h"
57#include "kdebug.h"
58#include "kdatetime.h"
59#include "kcalendarsystem.h"
60#include "kcurrencycode.h"
61#include "klocalizedstring.h"
62#include "kconfiggroup.h"
63#include "kcatalogname_p.h"
64#include "common_helpers_p.h"
65#include "kdayperiod_p.h"
66
67class KLocaleStaticData
68{
69public:
70
71 KLocaleStaticData();
72
73 QString maincatalog;
74
75 // FIXME: Temporary until full language-sensitivity implemented.
76 QHash<KLocale::DigitSet, QStringList> languagesUsingDigitSet;
77};
78
79KLocaleStaticData::KLocaleStaticData()
80{
81 // Languages using non-Western Arabic digit sets.
82 // FIXME: Temporary until full language-sensitivity implemented.
83 languagesUsingDigitSet.insert(KLocale::ArabicIndicDigits, QStringList() << QString::fromLatin1("ar") << QString::fromLatin1("ps"));
84 languagesUsingDigitSet.insert(KLocale::BengaliDigits, QStringList() << QString::fromLatin1("bn") << QString::fromLatin1("as") );
85 languagesUsingDigitSet.insert(KLocale::DevenagariDigits, QStringList() << QString::fromLatin1("hi") << QString::fromLatin1("ne"));
86 languagesUsingDigitSet.insert(KLocale::EasternArabicIndicDigits, QStringList() << QString::fromLatin1("fa") << QString::fromLatin1("ur"));
87 languagesUsingDigitSet.insert(KLocale::GujaratiDigits, QStringList() << QString::fromLatin1("gu") );
88 languagesUsingDigitSet.insert(KLocale::GurmukhiDigits, QStringList() << QString::fromLatin1("pa") );
89 languagesUsingDigitSet.insert(KLocale::KannadaDigits, QStringList() << QString::fromLatin1("kn") );
90 languagesUsingDigitSet.insert(KLocale::KhmerDigits, QStringList() << QString::fromLatin1("km") );
91 languagesUsingDigitSet.insert(KLocale::MalayalamDigits, QStringList() << QString::fromLatin1("ml") );
92 languagesUsingDigitSet.insert(KLocale::OriyaDigits, QStringList() << QString::fromLatin1("or") );
93 languagesUsingDigitSet.insert(KLocale::TamilDigits, QStringList() << QString::fromLatin1("ta") );
94 languagesUsingDigitSet.insert(KLocale::TeluguDigits, QStringList() << QString::fromLatin1("te") );
95 languagesUsingDigitSet.insert(KLocale::ThaiDigits, QStringList() << QString::fromLatin1("th"));
96}
97
98K_GLOBAL_STATIC(KLocaleStaticData, staticData)
99
100
101QDebug operator<<(QDebug debug, const KCatalogName &cn)
102{
103 return debug << cn.name << cn.loadCount;
104}
105
106KLocalePrivate::KLocalePrivate(KLocale *q_ptr)
107 : q(q_ptr),
108 m_config(KSharedConfig::Ptr()),
109 m_country(QString()),
110 m_language(QString()),
111 m_languages(0),
112 m_catalogName(QString()),
113 m_calendar(0),
114 m_currency(0),
115 m_codecForEncoding(0)
116{
117}
118
119KLocalePrivate::KLocalePrivate(const KLocalePrivate &rhs)
120{
121 copy(rhs);
122}
123
124KLocalePrivate &KLocalePrivate::operator=(const KLocalePrivate &rhs)
125{
126 copy(rhs);
127 return *this;
128}
129
130KConfig *KLocalePrivate::config()
131{
132 if (m_config != KSharedConfig::Ptr()) {
133 return m_config.data();
134 } else {
135 return KGlobal::config().data();
136 }
137}
138
139void KLocalePrivate::copy(const KLocalePrivate &rhs)
140{
141 // Parent KLocale
142 q = 0;
143
144 // Config
145 m_config = rhs.m_config;
146
147 // Country settings
148 m_country = rhs.m_country;
149 m_countryDivisionCode = rhs.m_countryDivisionCode;
150
151 // Language settings
152 m_language = rhs.m_language;
153 m_languages = 0;
154 m_languageList = rhs.m_languageList;
155 m_languageSensitiveDigits = rhs.m_languageSensitiveDigits;
156 m_nounDeclension = rhs.m_nounDeclension;
157
158 // Catalog settings
159 m_catalogName = rhs.m_catalogName;
160 m_catalogNames = rhs.m_catalogNames;
161 m_catalogs = rhs.m_catalogs;
162 m_numberOfSysCatalogs = rhs.m_numberOfSysCatalogs;
163 m_useTranscript = rhs.m_useTranscript;
164
165 // Calendar settings
166 m_calendarSystem = rhs.m_calendarSystem;
167 m_calendar = 0;
168 m_weekStartDay = rhs.m_weekStartDay;
169 m_workingWeekStartDay = rhs.m_workingWeekStartDay;
170 m_workingWeekEndDay = rhs.m_workingWeekEndDay;
171 m_weekDayOfPray = rhs.m_weekDayOfPray;
172
173 // Date/Time settings
174 m_dateFormat = rhs.m_dateFormat;
175 m_dateFormatShort = rhs.m_dateFormatShort;
176 m_timeFormat = rhs.m_timeFormat;
177 m_dateTimeDigitSet = rhs.m_dateTimeDigitSet;
178 m_dateMonthNamePossessive = rhs.m_dateMonthNamePossessive;
179 m_dayPeriods = rhs.m_dayPeriods;
180 m_weekNumberSystem = rhs.m_weekNumberSystem;
181
182 // Number settings
183 m_decimalPlaces = rhs.m_decimalPlaces;
184 m_decimalSymbol = rhs.m_decimalSymbol;
185 m_thousandsSeparator = rhs.m_thousandsSeparator;
186 m_numericDigitGrouping = rhs.m_numericDigitGrouping;
187 m_positiveSign = rhs.m_positiveSign;
188 m_negativeSign = rhs.m_negativeSign;
189 m_digitSet = rhs.m_digitSet;
190
191 // Currency settings
192 m_currencyCode = rhs.m_currencyCode;
193 m_currency = 0;
194 m_currencyCodeList = rhs.m_currencyCodeList;
195
196 // Money settings
197 m_currencySymbol = rhs.m_currencySymbol;
198 m_monetaryDecimalSymbol = rhs.m_monetaryDecimalSymbol;
199 m_monetaryThousandsSeparator = rhs.m_monetaryThousandsSeparator;
200 m_monetaryDigitGrouping = rhs.m_monetaryDigitGrouping;
201 m_monetaryDecimalPlaces = rhs.m_monetaryDecimalPlaces;
202 m_positiveMonetarySignPosition = rhs.m_positiveMonetarySignPosition;
203 m_negativeMonetarySignPosition = rhs.m_negativeMonetarySignPosition;
204 m_positivePrefixCurrencySymbol = rhs.m_positivePrefixCurrencySymbol;
205 m_negativePrefixCurrencySymbol = rhs.m_negativePrefixCurrencySymbol;
206 m_monetaryDigitSet = rhs.m_monetaryDigitSet;
207
208 // Units settings
209 m_binaryUnitDialect = rhs.m_binaryUnitDialect;
210 m_byteSizeFmt = rhs.m_byteSizeFmt;
211 m_pageSize = rhs.m_pageSize;
212 m_measureSystem = rhs.m_measureSystem;
213
214 // Encoding settings
215 m_encoding = rhs.m_encoding;
216 m_codecForEncoding = rhs.m_codecForEncoding;
217 m_utf8FileEncoding = rhs.m_utf8FileEncoding;
218}
219
220KLocalePrivate::~KLocalePrivate()
221{
222 delete m_currency;
223 delete m_calendar;
224 delete m_languages;
225}
226
227// init only called from platform specific constructor, so set everything up
228// Will be given a persistantConfig or a tempConfig or neither, but never both
229void KLocalePrivate::init(const QString& catalogName, const QString &language, const QString &country,
230 KSharedConfig::Ptr persistantConfig, KConfig *tempConfig)
231{
232 m_catalogName = catalogName;
233
234 // Only keep the persistant config if it is not the global
235 if (persistantConfig != KSharedConfig::Ptr() && persistantConfig != KGlobal::config()) {
236 m_config = persistantConfig;
237 }
238
239 KConfigGroup cg;
240 bool useEnvironmentVariables;
241
242 // We can't read the formats from the config until we know what locale to read in, but we need
243 // to read the config to find out the locale. The Country and Language settings should never
244 // be localized in the config, so we can read a temp copy of them to get us started.
245
246 // If no config given, use the global config and include envvars, otherwise use only the config.
247 if (m_config != KSharedConfig::Ptr()) {
248 cg = m_config->group(QLatin1String("Locale"));
249 useEnvironmentVariables = false;
250 } else if (tempConfig == 0 || tempConfig == KGlobal::config().data()) {
251 cg = KGlobal::config()->group(QLatin1String("Locale"));
252 useEnvironmentVariables = true;
253 } else {
254 cg = tempConfig->group(QLatin1String("Locale"));
255 useEnvironmentVariables = false;
256 }
257
258 initEncoding();
259 initFileNameEncoding();
260 initCountry(country, cg.readEntry(QLatin1String("Country")));
261 initLanguageList(language, cg.readEntry(QLatin1String("Language")), useEnvironmentVariables);
262 // Now that we have a language, we can set up the config which uses it to setLocale()
263 initConfig(tempConfig);
264 initMainCatalogs();
265 initFormat();
266}
267
268// Init the config, this is called during construction and by later setCountry/setLanguage calls.
269// You _must_ have the m_language set to a valid language or en_US before calling this so a
270// setLocale can be applied to the config
271void KLocalePrivate::initConfig(KConfig *config)
272{
273 // * If we were constructed with a KSharedConfig it means the user gave it to us
274 // to use for the life of the KLocale, so just keep using it after a setLocale
275 // * If passed in KConfig is null or the global config then use the global, but
276 // do the setLocale first.
277 // * If we have a KConfig we need to use that, but due to keeping old behaviour
278 // of not requiring access to it for life we can't keep a reference so instead
279 // take a copy and use that, but do setLocale first.
280
281 if (m_config != KSharedConfig::Ptr()) {
282 m_config->setLocale(m_language);
283 } else {
284 // If no config given then use the global
285 if (config == 0 || config == KGlobal::config().data()) {
286 KGlobal::config()->setLocale(m_language);
287 } else {
288 config->setLocale(m_language);
289 m_config = KSharedConfig::openConfig();
290 config->copyTo(QString(), m_config.data());
291 m_config->markAsClean();
292 }
293 }
294}
295
296void KLocalePrivate::initMainCatalogs()
297{
298 KLocaleStaticData *s = staticData;
299 QMutexLocker lock(kLocaleMutex());
300
301 if (!s->maincatalog.isEmpty()) {
302 // If setMainCatalog was called, then we use that
303 // (e.g. korgac calls setMainCatalog("korganizer") to use korganizer.po)
304 m_catalogName = s->maincatalog;
305 }
306
307 if (m_catalogName.isEmpty()) {
308 kDebug(173) << "KLocale instance created called without valid "
309 << "catalog! Give an argument or call setMainCatalog "
310 << "before init" << endl;
311 } else {
312 // do not use insertCatalog here, that would already trigger updateCatalogs
313 m_catalogNames.append(KCatalogName(m_catalogName)); // application catalog
314
315 // catalogs from which each application can draw translations
316 const int numberOfCatalogs = m_catalogNames.size();
317 m_catalogNames.append(KCatalogName(QString::fromLatin1("libphonon")));
318 m_catalogNames.append(KCatalogName(QString::fromLatin1("kio4")));
319 m_catalogNames.append(KCatalogName(QString::fromLatin1("kdelibs4")));
320 m_catalogNames.append(KCatalogName(QString::fromLatin1("kdeqt")));
321 m_catalogNames.append(KCatalogName(QString::fromLatin1("solid_qt")));
322 m_catalogNames.append(KCatalogName(QString::fromLatin1("kdecalendarsystems")));
323 m_numberOfSysCatalogs = m_catalogNames.size() - numberOfCatalogs;
324
325 updateCatalogs(); // evaluate this for all languages
326 }
327}
328
329void KLocalePrivate::getLanguagesFromVariable(QStringList &list, const char *variable, bool isLanguageList)
330{
331 QByteArray var(qgetenv(variable));
332 if (!var.isEmpty()) {
333 QString value = QFile::decodeName(var);
334 if (isLanguageList) {
335 list += value.split(QLatin1Char(':'));
336 } else {
337 // Process the value to create possible combinations.
338 QString lang, ctry, modf, cset;
339 KLocale::splitLocale(value, lang, ctry, modf, cset);
340
341 if (!ctry.isEmpty() && !modf.isEmpty()) {
342 list += lang + QLatin1Char('_') + ctry + QLatin1Char('@') + modf;
343 }
344 // NOTE: The priority is tricky in case both ctry and modf are present.
345 // Should really lang@modf be of higher priority than lang_ctry?
346 // For at least one case (Serbian language), it is better this way.
347 if (!modf.isEmpty()) {
348 list += lang + QLatin1Char('@') + modf;
349 }
350 if (!ctry.isEmpty()) {
351 list += lang + QLatin1Char('_') + ctry;
352 }
353 list += lang;
354 }
355 }
356}
357
358// init the country at construction only, will ensure we always have a country set
359void KLocalePrivate::initCountry(const QString &country, const QString &configCountry)
360{
361 // Cache the valid countries list and add the default C as it is valid to use
362 QStringList validCountries = allCountriesList();
363 validCountries.append( defaultCountry() );
364
365 // First check if the constructor passed in a value and if so if it is valid
366 QString putativeCountry = country;
367
368 if ( putativeCountry.isEmpty() || !validCountries.contains( putativeCountry, Qt::CaseInsensitive ) ) {
369
370 // If the requested country is not valid, try the country as set in the config:
371 putativeCountry = configCountry;
372
373 if ( putativeCountry.isEmpty() || !validCountries.contains( putativeCountry, Qt::CaseInsensitive ) ) {
374
375 // If the config country is not valid try the current host system country
376 putativeCountry = systemCountry();
377
378 if ( putativeCountry.isEmpty() || !validCountries.contains( putativeCountry, Qt::CaseInsensitive ) ) {
379 // Only if no other option, resort to the default C
380 putativeCountry = defaultCountry();
381 }
382 }
383 }
384
385 // Always save as lowercase, unless it's C when we want it uppercase
386 if ( putativeCountry.toLower() == defaultCountry().toLower() ) {
387 m_country = defaultCountry();
388 } else {
389 m_country = putativeCountry.toLower();
390 }
391}
392
393QString KLocalePrivate::systemCountry() const
394{
395 // Use QLocale for now as it supposedly provides a sensible default most times,
396 // e.g. if locale is only "de" it is assumed to mean country of "DE"
397 QString systemCountry, s1, s2, s3;
398 splitLocale( QLocale::system().name(), s1, systemCountry, s2, s3 );
399 return systemCountry.toLower();
400}
401
402void KLocalePrivate::initLanguageList(const QString &language, const QString &configLanguages,
403 bool useEnvironmentVariables)
404{
405 m_language = language;
406
407 // Collect possible languages by decreasing priority.
408 // The priority is as follows:
409 // - the internally set language, if any
410 // - KDE_LANG environment variable (can be a list)
411 // - KDE configuration (can be a list)
412 // - environment variables considered by gettext(3)
413 // The environment variables are not considered if useEnvironmentVariables is false.
414 QStringList list;
415 if (!m_language.isEmpty()) {
416 list += m_language;
417 }
418
419 // If the Locale object was created with a specific config file, then do not use the
420 // environmental variables. If the locale object was created with the global config, then
421 // do use the environmental variables.
422 if (useEnvironmentVariables) {
423 // KDE_LANG contains list of language codes, not locale string.
424 getLanguagesFromVariable(list, "KDE_LANG", true);
425 }
426
427 if (!configLanguages.isEmpty()) {
428 list += configLanguages.split(QLatin1Char(':'));
429 }
430
431 if (useEnvironmentVariables) {
432 // Collect languages by same order of priority as for gettext(3).
433 // LANGUAGE contains list of language codes, not locale string.
434 getLanguagesFromVariable(list, "LANGUAGE", true);
435 getLanguagesFromVariable(list, "LC_ALL");
436 getLanguagesFromVariable(list, "LC_MESSAGES");
437 getLanguagesFromVariable(list, "LANG");
438 }
439
440 // fall back to the system language
441 list += systemLanguageList();
442
443 // Send the list to filter for really present languages on the system.
444 setLanguage(list);
445}
446
447QStringList KLocalePrivate::systemLanguageList() const
448{
449 return QStringList();
450}
451
452void KLocalePrivate::initFormat()
453{
454 KConfigGroup cg(config(), "Locale");
455
456 KConfig entryFile(KStandardDirs::locate("locale", QString::fromLatin1("l10n/%1/entry.desktop").arg(m_country)));
457 entryFile.setLocale(m_language);
458 KConfigGroup entry(&entryFile, "KCM Locale");
459
460 //One-time conversion in 4.4 from FracDigits to DecimalPlaces and MonetaryDecimalPlaces
461 //If user has personal setting for FracDigits then use it for both Decimal Places
462 //TODO: Possible to do with kconf_update
463 if (cg.hasKey("FracDigits")) {
464 QString fracDigits = cg.readEntry("FracDigits", "");
465 if (!fracDigits.isEmpty()) {
466 cg.writeEntry("DecimalPlaces", fracDigits);
467 cg.writeEntry("MonetaryDecimalPlaces", fracDigits);
468 }
469 cg.deleteEntry("FracDigits");
470 cg.config()->sync();
471 }
472
473 // Numeric
474#define readConfigEntry(key, default, save) \
475 save = entry.readEntry(key, default); \
476 save = cg.readEntry(key, save);
477
478#define readConfigNumEntry(key, default, save, type) \
479 save = (type)entry.readEntry(key, int(default)); \
480 save = (type)cg.readEntry(key, int(save));
481
482 // Country settings
483 readConfigEntry("CountryDivisionCode", QString(), m_countryDivisionCode);
484
485 // Numeric formats
486 readConfigNumEntry("DecimalPlaces", 2, m_decimalPlaces, int);
487
488 readConfigEntry("DecimalSymbol", ".", m_decimalSymbol);
489 readConfigEntry("ThousandsSeparator", ",", m_thousandsSeparator);
490 m_thousandsSeparator.remove(QString::fromLatin1("$0"));
491 QString digitGroupFormat;
492 readConfigEntry("DigitGroupFormat", "3", digitGroupFormat);
493 m_numericDigitGrouping = digitGroupFormatToList(digitGroupFormat);
494
495 readConfigEntry("PositiveSign", "", m_positiveSign);
496 readConfigEntry("NegativeSign", "-", m_negativeSign);
497
498 readConfigNumEntry("DigitSet", KLocale::ArabicDigits, m_digitSet, KLocale::DigitSet);
499 // FIXME: Temporary until full language-sensitivity implemented.
500 readConfigEntry("LanguageSensitiveDigits", true, m_languageSensitiveDigits);
501
502 // Currency
503 readConfigEntry("CurrencyCode", "USD", m_currencyCode);
504 initCurrency();
505 readConfigEntry("CurrencySymbol", m_currency->defaultSymbol(), m_currencySymbol);
506 readConfigEntry("CurrencyCodesInUse", QStringList(m_currencyCode), m_currencyCodeList);
507
508 // Monetary formats
509 readConfigNumEntry("MonetaryDecimalPlaces", m_currency->decimalPlaces(), m_monetaryDecimalPlaces, int);
510
511 readConfigEntry("MonetaryDecimalSymbol", ".", m_monetaryDecimalSymbol);
512 readConfigEntry("MonetaryThousandsSeparator", ",", m_monetaryThousandsSeparator);
513 m_monetaryThousandsSeparator.remove(QString::fromLatin1("$0"));
514 readConfigEntry("MonetaryDigitGroupFormat", "3", digitGroupFormat);
515 m_monetaryDigitGrouping = digitGroupFormatToList(digitGroupFormat);
516
517 readConfigEntry("PositivePrefixCurrencySymbol", true, m_positivePrefixCurrencySymbol);
518 readConfigEntry("NegativePrefixCurrencySymbol", true, m_negativePrefixCurrencySymbol);
519 readConfigNumEntry("PositiveMonetarySignPosition", KLocale::BeforeQuantityMoney,
520 m_positiveMonetarySignPosition, KLocale::SignPosition);
521 readConfigNumEntry("NegativeMonetarySignPosition", KLocale::ParensAround,
522 m_negativeMonetarySignPosition, KLocale::SignPosition);
523
524 readConfigNumEntry("MonetaryDigitSet", KLocale::ArabicDigits,
525 m_monetaryDigitSet, KLocale::DigitSet);
526 readConfigNumEntry("BinaryUnitDialect", KLocale::IECBinaryDialect,
527 m_binaryUnitDialect, KLocale::BinaryUnitDialect);
528
529 // Date and time
530 readConfigEntry("TimeFormat", "%H:%M:%S", m_timeFormat);
531 readConfigEntry("DateFormat", "%A %d %B %Y", m_dateFormat);
532 readConfigEntry("DateFormatShort", "%Y-%m-%d", m_dateFormatShort);
533 readConfigNumEntry("WeekStartDay", 1, m_weekStartDay, int); //default to Monday
534 readConfigNumEntry("WorkingWeekStartDay", 1, m_workingWeekStartDay, int); //default to Monday
535 readConfigNumEntry("WorkingWeekEndDay", 5, m_workingWeekEndDay, int); //default to Friday
536 readConfigNumEntry("WeekDayOfPray", 7, m_weekDayOfPray, int); //default to Sunday
537 readConfigNumEntry("DateTimeDigitSet", KLocale::ArabicDigits,
538 m_dateTimeDigitSet, KLocale::DigitSet);
539 readConfigNumEntry("WeekNumberSystem", KLocale::IsoWeekNumber,
540 m_weekNumberSystem, KLocale::WeekNumberSystem);
541
542 // other
543#ifndef QT_NO_PRINTER
544 readConfigNumEntry("PageSize", QPrinter::A4, m_pageSize, QPrinter::PageSize);
545#endif
546 readConfigNumEntry("MeasureSystem", KLocale::Metric, m_measureSystem, KLocale::MeasureSystem);
547 QString calendarType;
548 readConfigEntry("CalendarSystem", "gregorian", calendarType);
549 setCalendar(calendarType);
550
551 readConfigEntry("Transcript", true, m_useTranscript);
552
553 //Grammatical
554 //Precedence here is l10n / i18n / config file
555 KConfig langCfg(KStandardDirs::locate("locale", QString::fromLatin1("%1/entry.desktop").arg(m_language)));
556 KConfigGroup lang(&langCfg, "KCM Locale");
557#define read3ConfigBoolEntry(key, default, save) \
558 save = entry.readEntry(key, default); \
559 save = lang.readEntry(key, save); \
560 save = cg.readEntry(key, save);
561
562 read3ConfigBoolEntry("NounDeclension", false, m_nounDeclension);
563 read3ConfigBoolEntry("DateMonthNamePossessive", false, m_dateMonthNamePossessive);
564
565 initDayPeriods(cg);
566}
567
568void KLocalePrivate::initDayPeriods(const KConfigGroup &cg)
569{
570 // Prefer any l10n file value for country/language,
571 // otherwise default to language only value which will be filled in later when i18n available
572
573 //Day Period are stored in config as one QStringList entry per Day Period
574 //PeriodCode,LongName,ShortName,NarrowName,StartTime,EndTime,Offset,OffsetIfZero
575 //where start and end time are in the format HH:MM:SS.MMM
576
577 m_dayPeriods.clear();
578 QString periodKey = QString::fromLatin1("DayPeriod1");
579 int i = 1;
580 while (cg.hasKey(periodKey)) {
581 QStringList period = cg.readEntry(periodKey, QStringList());
582 if (period.count() == 8) {
583 m_dayPeriods.append(KDayPeriod(period[0], period[1], period[2], period[3],
584 QTime::fromString(period[4], QString::fromLatin1("HH:mm:ss.zzz")),
585 QTime::fromString(period[5], QString::fromLatin1("HH:mm:ss.zzz")),
586 period[6].toInt(), period[7].toInt()));
587 }
588 i = i + 1;
589 periodKey = QString::fromLatin1("DayPeriod%1").arg(i);
590 }
591}
592
593bool KLocalePrivate::setCountry(const QString &country, KConfig *newConfig)
594{
595 // Cache the valid countries list and add the default C as it is valid to use
596 QStringList validCountries = allCountriesList();
597 validCountries.append(defaultCountry());
598
599 QString putativeCountry = country;
600
601 if (putativeCountry.isEmpty()) {
602 // An empty string means to use the system country
603 putativeCountry = systemCountry();
604 if (putativeCountry.isEmpty() || !validCountries.contains(putativeCountry, Qt::CaseInsensitive)) {
605 // If the system country is not valid, use the default
606 putativeCountry = defaultCountry();
607 }
608 } else if (!validCountries.contains(putativeCountry, Qt::CaseInsensitive)) {
609 return false;
610 }
611
612 // Always save as lowercase, unless it's C when we want it uppercase
613 if (putativeCountry.toLower() == defaultCountry().toLower()) {
614 m_country = defaultCountry();
615 } else {
616 m_country = putativeCountry.toLower();
617 }
618
619 // Get rid of the old config, start again with the new
620 m_config = KSharedConfig::Ptr();
621 initConfig(newConfig);
622
623 // Init all the settings
624 initFormat();
625
626 return true;
627}
628
629bool KLocalePrivate::setCountryDivisionCode(const QString &countryDivisionCode)
630{
631 m_countryDivisionCode = countryDivisionCode;
632 return true;
633}
634
635bool KLocalePrivate::setLanguage(const QString &language, KConfig *config)
636{
637 QMutexLocker lock(kLocaleMutex());
638 m_languageList.removeAll(language);
639 m_languageList.prepend(language); // let us consider this language to be the most important one
640
641 m_language = language; // remember main language for shortcut evaluation
642
643 // important when called from the outside and harmless when called before
644 // populating the catalog name list
645 updateCatalogs();
646
647 // Get rid of the old config, start again with the new
648 m_config = KSharedConfig::Ptr();
649 initConfig(config);
650
651 // Init the new format settings
652 initFormat();
653
654 // Maybe the mo-files for this language are empty, but in principle we can speak all languages
655 return true;
656}
657
658// KDE5 Unlike the other setLanguage call this does not reparse the config so the localized config
659// settings for the new primary language will _not_ be loaded. In KDE5 always keep the original
660// config so this can be reparsed when required.
661bool KLocalePrivate::setLanguage(const QStringList &languages)
662{
663 QMutexLocker lock(kLocaleMutex());
664 // This list might contain
665 // 1) some empty strings that we have to eliminate
666 // 2) duplicate entries like in de:fr:de, where we have to keep the first occurrence of a
667 // language in order to preserve the order of precenence of the user
668 // 3) languages into which the application is not translated. For those languages we should not
669 // even load kdelibs.mo or kio.po. these languages have to be dropped. Otherwise we get
670 // strange side effects, e.g. with Hebrew: the right/left switch for languages that write
671 // from right to left (like Hebrew or Arabic) is set in kdelibs.mo. If you only have
672 // kdelibs.mo but nothing from appname.mo, you get a mostly English app with layout from
673 // right to left. That was considered to be a bug by the Hebrew translators.
674 QStringList list;
675 foreach(const QString &language, languages) {
676 if (!language.isEmpty() && !list.contains(language) && isApplicationTranslatedInto(language)) {
677 list.append(language);
678 }
679 }
680
681 if (!list.contains(KLocale::defaultLanguage())) {
682 // English should always be added as final possibility; this is important
683 // for proper initialization of message text post-processors which are
684 // needed for English too, like semantic to visual formatting, etc.
685 list.append(KLocale::defaultLanguage());
686 }
687
688 m_language = list.first(); // keep this for shortcut evaluations
689
690 m_languageList = list; // keep this new list of languages to use
691
692 // important when called from the outside and harmless when called before populating the
693 // catalog name list
694 updateCatalogs();
695
696 return true; // we found something. Maybe it's only English, but we found something
697}
698
699void KLocalePrivate::initCurrency()
700{
701 if (m_currencyCode.isEmpty() || !KCurrencyCode::isValid(m_currencyCode)) {
702 m_currencyCode = KLocale::defaultCurrencyCode();
703 }
704
705 if (!m_currency || m_currencyCode != m_currency->isoCurrencyCode() || !m_currency->isValid()) {
706 delete m_currency;
707 m_currency = new KCurrencyCode(m_currencyCode, m_language);
708 }
709}
710
711void KLocalePrivate::setCurrencyCode(const QString &newCurrencyCode)
712{
713 if (!newCurrencyCode.isEmpty() && newCurrencyCode != m_currency->isoCurrencyCode() &&
714 KCurrencyCode::isValid(newCurrencyCode)) {
715 m_currencyCode = newCurrencyCode;
716 initCurrency();
717 }
718}
719
720bool KLocalePrivate::isApplicationTranslatedInto(const QString &lang)
721{
722 if (lang.isEmpty()) {
723 return false;
724 }
725
726 if (lang == KLocale::defaultLanguage()) {
727 // default language is always "installed"
728 return true;
729 }
730
731 if (m_catalogName.isEmpty()) {
732 kDebug() << "no appName!";
733 return false;
734 }
735
736 if (!KCatalog::catalogLocaleDir(m_catalogName, lang).isEmpty()) {
737 return true;
738 }
739 return false;
740}
741
742void KLocalePrivate::splitLocale(const QString &aLocale, QString &language, QString &country,
743 QString &modifier, QString &charset)
744{
745 QString locale = aLocale;
746
747 language.clear();
748 country.clear();
749 modifier.clear();
750 charset.clear();
751
752 // In case there are several concatenated locale specifications,
753 // truncate all but first.
754 int f = locale.indexOf(QLatin1Char(':'));
755 if (f >= 0) {
756 locale.truncate(f);
757 }
758
759 f = locale.indexOf(QLatin1Char('.'));
760 if (f >= 0) {
761 charset = locale.mid(f + 1);
762 locale.truncate(f);
763 }
764
765 f = locale.indexOf(QLatin1Char('@'));
766 if (f >= 0) {
767 modifier = locale.mid(f + 1);
768 locale.truncate(f);
769 }
770
771 f = locale.indexOf(QLatin1Char('_'));
772 if (f >= 0) {
773 country = locale.mid(f + 1);
774 locale.truncate(f);
775 }
776
777 language = locale;
778}
779
780QString KLocalePrivate::language() const
781{
782 return m_language;
783}
784
785QString KLocalePrivate::country() const
786{
787 return m_country;
788}
789
790QString KLocalePrivate::countryDivisionCode() const
791{
792 if (m_countryDivisionCode.isEmpty()) {
793 return country().toUpper();
794 } else {
795 return m_countryDivisionCode;
796 }
797}
798
799KCurrencyCode *KLocalePrivate::currency()
800{
801 if (!m_currency) {
802 initCurrency();
803 }
804 return m_currency;
805}
806
807QString KLocalePrivate::currencyCode() const
808{
809 return m_currencyCode;
810}
811
812void KLocalePrivate::insertCatalog(const QString &catalog)
813{
814 QMutexLocker lock(kLocaleMutex());
815 int pos = m_catalogNames.indexOf(KCatalogName(catalog));
816 if (pos != -1) {
817 ++m_catalogNames[pos].loadCount;
818 return;
819 }
820
821 // Insert new catalog just before system catalogs, to preserve the
822 // lowest priority of system catalogs.
823 m_catalogNames.insert(m_catalogNames.size() - m_numberOfSysCatalogs, KCatalogName(catalog));
824 updateCatalogs(); // evaluate the changed list and generate the necessary KCatalog objects
825}
826
827void KLocalePrivate::updateCatalogs()
828{
829 // some changes have occurred. Maybe we have learned or forgotten some languages.
830 // Maybe the language precedence has changed.
831 // Maybe we have learned or forgotten some catalog names.
832
833 QList<KCatalog> newCatalogs;
834
835 // now iterate over all languages and all wanted catalog names and append or create them in the
836 // right order the sequence must be e.g. nds/appname nds/kdelibs nds/kio de/appname de/kdelibs
837 // de/kio etc. and not nds/appname de/appname nds/kdelibs de/kdelibs etc. Otherwise we would be
838 // in trouble with a language sequende nds,<default>,de. In this case <default> must hide
839 // everything after itself in the language list.
840 foreach(const QString &lang, m_languageList) {
841 if (lang == KLocale::defaultLanguage()) {
842 // Default language has no catalogs (messages from the code),
843 // so loading catalogs for languages below the default
844 // would later confuse the fallback resolution.
845 break;
846 }
847 foreach(const KCatalogName &name, m_catalogNames) {
848 // create and add catalog for this name and language if it exists
849 if (! KCatalog::catalogLocaleDir(name.name, lang).isEmpty()) {
850 newCatalogs.append(KCatalog(name.name, lang));
851 //kDebug(173) << "Catalog: " << name << ":" << lang;
852 }
853 }
854 }
855
856 // notify KLocalizedString of catalog update.
857 m_catalogs = newCatalogs;
858 KLocalizedString::notifyCatalogsUpdated(m_languageList, m_catalogNames);
859}
860
861void KLocalePrivate::removeCatalog(const QString &catalog)
862{
863 QMutexLocker lock(kLocaleMutex());
864 int pos = m_catalogNames.indexOf(KCatalogName(catalog));
865 if (pos == -1) {
866 return;
867 }
868 if (--m_catalogNames[pos].loadCount > 0) {
869 return;
870 }
871 m_catalogNames.removeAt(pos);
872 if (KGlobal::hasMainComponent()) {
873 // walk through the KCatalog instances and weed out everything we no longer need
874 updateCatalogs();
875 }
876}
877
878void KLocalePrivate::setActiveCatalog(const QString &catalog)
879{
880 QMutexLocker lock(kLocaleMutex());
881 int pos = m_catalogNames.indexOf(KCatalogName(catalog));
882 if (pos == -1) {
883 return;
884 }
885 m_catalogNames.move(pos, 0);
886 // walk through the KCatalog instances and adapt to the new order
887 updateCatalogs();
888}
889
890void KLocalePrivate::translateRawFrom(const char *catname, const char *msgctxt, const char *msgid, const char *msgid_plural,
891 unsigned long n, QString *language, QString *translation) const
892{
893 if (!msgid || !msgid[0]) {
894 kDebug(173) << "KLocale: trying to look up \"\" in catalog. "
895 << "Fix the program" << endl;
896 language->clear();
897 translation->clear();
898 return;
899 }
900 if (msgctxt && !msgctxt[0]) {
901 kDebug(173) << "KLocale: trying to use \"\" as context to message. "
902 << "Fix the program" << endl;
903 }
904 if (msgid_plural && !msgid_plural[0]) {
905 kDebug(173) << "KLocale: trying to use \"\" as plural message. "
906 << "Fix the program" << endl;
907 }
908
909 QMutexLocker locker(kLocaleMutex());
910 // determine the fallback string
911 QString fallback;
912 if (msgid_plural == NULL) {
913 fallback = QString::fromUtf8(msgid);
914 } else {
915 if (n == 1) {
916 fallback = QString::fromUtf8(msgid);
917 } else {
918 fallback = QString::fromUtf8(msgid_plural);
919 }
920 }
921 if (language) {
922 *language = KLocale::defaultLanguage();
923 }
924 if (translation) {
925 *translation = fallback;
926 }
927
928 // shortcut evaluation if default language is main language: do not consult the catalogs
929 if (useDefaultLanguage()) {
930 return;
931 }
932
933 const QList<KCatalog> catalogList = m_catalogs;
934 QString catNameDecoded;
935 if (catname != NULL) {
936 catNameDecoded = QString::fromUtf8(catname);
937 }
938 for (QList<KCatalog>::ConstIterator it = catalogList.constBegin(); it != catalogList.constEnd();
939 ++it) {
940 // shortcut evaluation: once we have arrived at default language, we cannot consult
941 // the catalog as it will not have an assiciated mo-file. For this default language we can
942 // immediately pick the fallback string.
943 if ((*it).language() == KLocale::defaultLanguage()) {
944 return;
945 }
946
947 if (catNameDecoded.isEmpty() || catNameDecoded == (*it).name()) {
948 QString text;
949 if (msgctxt != NULL && msgid_plural != NULL) {
950 text = (*it).translateStrict(msgctxt, msgid, msgid_plural, n);
951 } else if (msgid_plural != NULL) {
952 text = (*it).translateStrict(msgid, msgid_plural, n);
953 } else if (msgctxt != NULL) {
954 text = (*it).translateStrict(msgctxt, msgid);
955 } else {
956 text = (*it).translateStrict(msgid);
957 }
958
959 if (!text.isEmpty()) {
960 // we found it
961 if (language) {
962 *language = (*it).language();
963 }
964 if (translation) {
965 *translation = text;
966 }
967 return;
968 }
969 }
970 }
971}
972
973QString KLocalePrivate::translateQt(const char *context, const char *sourceText, const char *comment) const
974{
975 // Qt's context is normally the name of the class of the method which makes
976 // the tr(sourceText) call. However, it can also be manually supplied via
977 // translate(context, sourceText) call.
978 //
979 // Qt's sourceText is the actual message displayed to the user.
980 //
981 // Qt's comment is an optional argument of tr() and translate(), like
982 // tr(sourceText, comment) and translate(context, sourceText, comment).
983 //
984 // We handle this in the following way:
985 //
986 // If the comment is given, then it is considered gettext's msgctxt, so a
987 // context call is made.
988 //
989 // If the comment is not given, but context is given, then we treat it as
990 // msgctxt only if it was manually supplied (the one in translate()) -- but
991 // we don't know this, so we first try a context call, and if translation
992 // is not found, we fallback to ordinary call.
993 //
994 // If neither comment nor context are given, it's just an ordinary call
995 // on sourceText.
996
997 if (!sourceText || !sourceText[0]) {
998 kDebug(173) << "KLocale: trying to look up \"\" in catalog. "
999 << "Fix the program" << endl;
1000 return QString();
1001 }
1002
1003 if (useDefaultLanguage()) {
1004 return QString();
1005 }
1006
1007 QString translation;
1008 QString language;
1009
1010 // NOTE: Condition (language != defaultLanguage()) means that translation
1011 // was found, otherwise we got the original string back as translation.
1012
1013 if (comment && comment[0]) {
1014 // Comment given, go for context call.
1015 translateRawFrom(0, comment, sourceText, 0, 0, &language, &translation);
1016 } else {
1017 // Comment not given, go for try-fallback with context.
1018 if (context && context[0]) {
1019 translateRawFrom(0, context, sourceText, 0, 0, &language, &translation);
1020 }
1021 if (language.isEmpty() || language == defaultLanguage()) {
1022 translateRawFrom(0, 0, sourceText, 0, 0, &language, &translation);
1023 }
1024 }
1025
1026 if (language != defaultLanguage()) {
1027 return translation;
1028 }
1029
1030 // No proper translation found, return empty according to Qt's expectation.
1031 return QString();
1032}
1033
1034QList<KLocale::DigitSet> KLocalePrivate::allDigitSetsList() const
1035{
1036 QList<KLocale::DigitSet> digitSets;
1037 digitSets.append(KLocale::ArabicDigits);
1038 digitSets.append(KLocale::ArabicIndicDigits);
1039 digitSets.append(KLocale::BengaliDigits);
1040 digitSets.append(KLocale::DevenagariDigits);
1041 digitSets.append(KLocale::EasternArabicIndicDigits);
1042 digitSets.append(KLocale::GujaratiDigits);
1043 digitSets.append(KLocale::GurmukhiDigits);
1044 digitSets.append(KLocale::KannadaDigits);
1045 digitSets.append(KLocale::KhmerDigits);
1046 digitSets.append(KLocale::MalayalamDigits);
1047 digitSets.append(KLocale::OriyaDigits);
1048 digitSets.append(KLocale::TamilDigits);
1049 digitSets.append(KLocale::TeluguDigits);
1050 digitSets.append(KLocale::ThaiDigits);
1051 qSort(digitSets);
1052 return digitSets;
1053}
1054
1055QString KLocalePrivate::digitSetString(KLocale::DigitSet digitSet)
1056{
1057 switch (digitSet) {
1058 case KLocale::ArabicIndicDigits:
1059 return QString::fromUtf8("٠١٢٣٤٥٦٧٨٩");
1060 case KLocale::BengaliDigits:
1061 return QString::fromUtf8("০১২৩৪৫৬৭৮৯");
1062 case KLocale::DevenagariDigits:
1063 return QString::fromUtf8("०१२३४५६७८९");
1064 case KLocale::EasternArabicIndicDigits:
1065 return QString::fromUtf8("۰۱۲۳۴۵۶۷۸۹");
1066 case KLocale::GujaratiDigits:
1067 return QString::fromUtf8("૦૧૨૩૪૫૬૭૮૯");
1068 case KLocale::GurmukhiDigits:
1069 return QString::fromUtf8("੦੧੨੩੪੫੬੭੮੯");
1070 case KLocale::KannadaDigits:
1071 return QString::fromUtf8("೦೧೨೩೪೫೬೭೮೯");
1072 case KLocale::KhmerDigits:
1073 return QString::fromUtf8("០១២៣៤៥៦៧៨៩");
1074 case KLocale::MalayalamDigits:
1075 return QString::fromUtf8("൦൧൨൩൪൫൬൭൮൯");
1076 case KLocale::OriyaDigits:
1077 return QString::fromUtf8("୦୧୨୩୪୫୬୭୮୯");
1078 case KLocale::TamilDigits:
1079 return QString::fromUtf8("௦௧௨௩௪௫௬௭௮");
1080 case KLocale::TeluguDigits:
1081 return QString::fromUtf8("౦౧౨౩౪౫౬౭౯");
1082 case KLocale::ThaiDigits:
1083 return QString::fromUtf8("๐๑๒๓๔๕๖๗๘๙");
1084 default:
1085 return QString::fromUtf8("0123456789");
1086 }
1087}
1088
1089QString KLocalePrivate::digitSetToName(KLocale::DigitSet digitSet, bool withDigits) const
1090{
1091 QString name;
1092 switch (digitSet) {
1093 case KLocale::ArabicIndicDigits:
1094 name = i18nc("digit set", "Arabic-Indic");
1095 break;
1096 case KLocale::BengaliDigits:
1097 name = i18nc("digit set", "Bengali");
1098 break;
1099 case KLocale::DevenagariDigits:
1100 name = i18nc("digit set", "Devanagari");
1101 break;
1102 case KLocale::EasternArabicIndicDigits:
1103 name = i18nc("digit set", "Eastern Arabic-Indic");
1104 break;
1105 case KLocale::GujaratiDigits:
1106 name = i18nc("digit set", "Gujarati");
1107 break;
1108 case KLocale::GurmukhiDigits:
1109 name = i18nc("digit set", "Gurmukhi");
1110 break;
1111 case KLocale::KannadaDigits:
1112 name = i18nc("digit set", "Kannada");
1113 break;
1114 case KLocale::KhmerDigits:
1115 name = i18nc("digit set", "Khmer");
1116 break;
1117 case KLocale::MalayalamDigits:
1118 name = i18nc("digit set", "Malayalam");
1119 break;
1120 case KLocale::OriyaDigits:
1121 name = i18nc("digit set", "Oriya");
1122 break;
1123 case KLocale::TamilDigits:
1124 name = i18nc("digit set", "Tamil");
1125 break;
1126 case KLocale::TeluguDigits:
1127 name = i18nc("digit set", "Telugu");
1128 break;
1129 case KLocale::ThaiDigits:
1130 name = i18nc("digit set", "Thai");
1131 break;
1132 default:
1133 name = i18nc("digit set", "Arabic");
1134 }
1135 if (withDigits) {
1136 QString digits = digitSetString(digitSet);
1137 QString nameWithDigits = i18nc("name of digit set with digit string, "
1138 "e.g. 'Arabic (0123456789)'", "%1 (%2)", name, digits);
1139 return nameWithDigits;
1140 } else {
1141 return name;
1142 }
1143}
1144
1145QString KLocalePrivate::convertDigits(const QString &str, KLocale::DigitSet digitSet, bool ignoreContext) const
1146{
1147 if (!ignoreContext) {
1148 // Fall back to Western Arabic digits if requested digit set
1149 // is not appropriate for current application language.
1150 // FIXME: Temporary until full language-sensitivity implemented.
1151 KLocaleStaticData *s = staticData;
1152 if (m_languageSensitiveDigits && !s->languagesUsingDigitSet[digitSet].contains(m_language)) {
1153 digitSet = KLocale::ArabicDigits;
1154 }
1155 }
1156
1157 QString nstr;
1158 QString digitDraw = digitSetString(digitSet);
1159 foreach(const QChar &c, str) {
1160 if (c.isDigit()) {
1161 nstr += digitDraw[c.digitValue()];
1162 } else {
1163 nstr += c;
1164 }
1165 }
1166 return nstr;
1167}
1168
1169QString KLocalePrivate::toArabicDigits(const QString &str)
1170{
1171 QString nstr;
1172 foreach(const QChar &c, str) {
1173 if (c.isDigit()) {
1174 nstr += QChar('0' + c.digitValue());
1175 } else {
1176 nstr += c;
1177 }
1178 }
1179 return nstr;
1180}
1181
1182bool KLocalePrivate::nounDeclension() const
1183{
1184 return m_nounDeclension;
1185}
1186
1187bool KLocalePrivate::dateMonthNamePossessive() const
1188{
1189 return m_dateMonthNamePossessive;
1190}
1191
1192int KLocalePrivate::weekStartDay() const
1193{
1194 return m_weekStartDay;
1195}
1196
1197int KLocalePrivate::workingWeekStartDay() const
1198{
1199 return m_workingWeekStartDay;
1200}
1201
1202int KLocalePrivate::workingWeekEndDay() const
1203{
1204 return m_workingWeekEndDay;
1205}
1206
1207int KLocalePrivate::weekDayOfPray() const
1208{
1209 return m_weekDayOfPray;
1210}
1211
1212int KLocalePrivate::decimalPlaces() const
1213{
1214 return m_decimalPlaces;
1215}
1216
1217QString KLocalePrivate::decimalSymbol() const
1218{
1219 return m_decimalSymbol;
1220}
1221
1222QString KLocalePrivate::thousandsSeparator() const
1223{
1224 return m_thousandsSeparator;
1225}
1226
1227QList<int> KLocalePrivate::numericDigitGrouping() const
1228{
1229 return m_numericDigitGrouping;
1230}
1231
1232QString KLocalePrivate::currencySymbol() const
1233{
1234 return m_currencySymbol;
1235}
1236
1237QString KLocalePrivate::monetaryDecimalSymbol() const
1238{
1239 return m_monetaryDecimalSymbol;
1240}
1241
1242QString KLocalePrivate::monetaryThousandsSeparator() const
1243{
1244 return m_monetaryThousandsSeparator;
1245}
1246
1247QList<int> KLocalePrivate::monetaryDigitGrouping() const
1248{
1249 return m_monetaryDigitGrouping;
1250}
1251
1252QString KLocalePrivate::positiveSign() const
1253{
1254 return m_positiveSign;
1255}
1256
1257QString KLocalePrivate::negativeSign() const
1258{
1259 return m_negativeSign;
1260}
1261
1262/* Just copy to keep the diff looking clean, delete later
1263int KLocale::fracDigits() const
1264{
1265 return monetaryDecimalPlaces();
1266}
1267*/
1268
1269int KLocalePrivate::monetaryDecimalPlaces() const
1270{
1271 return m_monetaryDecimalPlaces;
1272}
1273
1274bool KLocalePrivate::positivePrefixCurrencySymbol() const
1275{
1276 return m_positivePrefixCurrencySymbol;
1277}
1278
1279bool KLocalePrivate::negativePrefixCurrencySymbol() const
1280{
1281 return m_negativePrefixCurrencySymbol;
1282}
1283
1284KLocale::SignPosition KLocalePrivate::positiveMonetarySignPosition() const
1285{
1286 return m_positiveMonetarySignPosition;
1287}
1288
1289KLocale::SignPosition KLocalePrivate::negativeMonetarySignPosition() const
1290{
1291 return m_negativeMonetarySignPosition;
1292}
1293
1294static inline void put_it_in(QChar *buffer, int &index, const QString &s)
1295{
1296 for (int l = 0; l < s.length(); l++) {
1297 buffer[index++] = s.at(l);
1298 }
1299}
1300
1301static inline void put_it_in(QChar *buffer, int &index, int number)
1302{
1303 buffer[index++] = number / 10 + '0';
1304 buffer[index++] = number % 10 + '0';
1305}
1306
1307// Convert POSIX Digit Group Format string into a Qlist<int>, e.g. "3;2" converts to (3,2)
1308QList<int> KLocalePrivate::digitGroupFormatToList(const QString &digitGroupFormat) const
1309{
1310 QList<int> groupList;
1311 QStringList stringList = digitGroupFormat.split(QLatin1Char(';'));
1312 foreach(const QString &size, stringList) {
1313 groupList.append(size.toInt());
1314 }
1315 return groupList;
1316}
1317
1318// Inserts all required occurrences of the group separator into a number string.
1319QString KLocalePrivate::formatDigitGroup(const QString &number, const QString &groupSeparator, const QString &decimalSeperator, QList<int> groupList) const
1320{
1321 if (groupList.isEmpty() || groupSeparator.isEmpty()) {
1322 return number;
1323 }
1324
1325 QString num = number;
1326 int groupCount = groupList.count();
1327 int groupAt = 0;
1328 int groupSize = groupList.at(groupAt);
1329 int pos = num.indexOf(decimalSeperator);
1330 if (pos == -1) {
1331 pos = num.length();
1332 }
1333 pos = pos - groupSize;
1334
1335 while (pos > 0 && groupSize > 0) {
1336 num.insert(pos, groupSeparator);
1337 if (groupAt + 1 < groupCount) {
1338 ++groupAt;
1339 groupSize = groupList.at(groupAt);
1340 }
1341 pos = pos - groupSize;
1342 }
1343
1344 return num;
1345}
1346
1347// Strips all occurrences of the group separator from a number, returns ok if the separators were all in the valid positions
1348QString KLocalePrivate::parseDigitGroup(const QString &number, const QString &groupSeparator, const QString &decimalSeparator, QList<int> groupList, bool *ok) const
1349{
1350 QString num = number;
1351 bool valid = true;
1352
1353 if (!groupSeparator.isEmpty()) {
1354 if (!groupList.isEmpty()) {
1355 int separatorSize = groupSeparator.length();
1356 int groupCount = groupList.count();
1357 int groupAt = 0;
1358 int groupSize = groupList.at(groupAt);
1359 int pos = number.indexOf(decimalSeparator);
1360 if (pos == -1) {
1361 pos = number.length();
1362 }
1363 pos = pos - groupSize - separatorSize;
1364
1365 while (pos > 0 && valid && groupSize > 0) {
1366 if (num.mid(pos, separatorSize) == groupSeparator) {
1367 num.remove(pos, separatorSize);
1368 if (groupAt + 1 < groupCount) {
1369 ++groupAt;
1370 groupSize = groupList.at(groupAt);
1371 }
1372 pos = pos - groupSize - separatorSize;
1373 } else {
1374 valid = false;
1375 }
1376 }
1377 }
1378
1379 if (num.contains(groupSeparator)) {
1380 valid = false;
1381 num = num.remove(groupSeparator);
1382 }
1383 }
1384
1385 if (ok) {
1386 *ok = valid;
1387 }
1388
1389 return num;
1390}
1391
1392QString KLocalePrivate::formatMoney(double num, const QString &symbol, int precision) const
1393{
1394 // some defaults
1395 QString currencyString = symbol;
1396 if (symbol.isNull()) {
1397 currencyString = currencySymbol();
1398 }
1399 if (precision < 0) {
1400 precision = monetaryDecimalPlaces();
1401 }
1402
1403 // the number itself
1404 bool neg = num < 0;
1405 QString res = QString::number(neg ? -num : num, 'f', precision);
1406
1407 // Replace dot with locale decimal separator
1408 res.replace(QLatin1Char('.'), monetaryDecimalSymbol());
1409
1410 // Insert the thousand separators
1411 res = formatDigitGroup(res, monetaryThousandsSeparator(), monetaryDecimalSymbol(), monetaryDigitGrouping());
1412
1413 // set some variables we need later
1414 int signpos = neg
1415 ? negativeMonetarySignPosition()
1416 : positiveMonetarySignPosition();
1417 QString sign = neg
1418 ? negativeSign()
1419 : positiveSign();
1420
1421 switch (signpos) {
1422 case KLocale::ParensAround:
1423 res.prepend(QLatin1Char('('));
1424 res.append(QLatin1Char(')'));
1425 break;
1426 case KLocale::BeforeQuantityMoney:
1427 res.prepend(sign);
1428 break;
1429 case KLocale::AfterQuantityMoney:
1430 res.append(sign);
1431 break;
1432 case KLocale::BeforeMoney:
1433 currencyString.prepend(sign);
1434 break;
1435 case KLocale::AfterMoney:
1436 currencyString.append(sign);
1437 break;
1438 }
1439
1440 if (neg ? negativePrefixCurrencySymbol() :
1441 positivePrefixCurrencySymbol()) {
1442 res.prepend(QLatin1Char(' '));
1443 res.prepend(currencyString);
1444 } else {
1445 res.append(QLatin1Char(' '));
1446 res.append(currencyString);
1447 }
1448
1449 // Convert to target digit set.
1450 res = convertDigits(res, m_monetaryDigitSet);
1451
1452 return res;
1453}
1454
1455
1456QString KLocalePrivate::formatNumber(double num, int precision) const
1457{
1458 if (precision < 0) {
1459 precision = decimalPlaces();
1460 }
1461 // no need to round since QString::number does this for us
1462 return formatNumber(QString::number(num, 'f', precision), false, 0);
1463}
1464
1465QString KLocalePrivate::formatLong(long num) const
1466{
1467 return formatNumber((double)num, 0);
1468}
1469
1470// increase the digit at 'position' by one
1471static void _inc_by_one(QString &str, int position)
1472{
1473 for (int i = position; i >= 0; i--) {
1474 char last_char = str[i].toLatin1();
1475 switch (last_char) {
1476 case '0':
1477 str[i] = '1';
1478 break;
1479 case '1':
1480 str[i] = '2';
1481 break;
1482 case '2':
1483 str[i] = '3';
1484 break;
1485 case '3':
1486 str[i] = '4';
1487 break;
1488 case '4':
1489 str[i] = '5';
1490 break;
1491 case '5':
1492 str[i] = '6';
1493 break;
1494 case '6':
1495 str[i] = '7';
1496 break;
1497 case '7':
1498 str[i] = '8';
1499 break;
1500 case '8':
1501 str[i] = '9';
1502 break;
1503 case '9':
1504 str[i] = '0';
1505 if (i == 0) str.prepend(QLatin1Char('1'));
1506 continue;
1507 case '.':
1508 continue;
1509 }
1510 break;
1511 }
1512}
1513
1514// Cut off if more digits in fractional part than 'precision'
1515static void _round(QString &str, int precision)
1516{
1517 int decimalSymbolPos = str.indexOf(QLatin1Char('.'));
1518
1519 if (decimalSymbolPos == -1) {
1520 if (precision == 0) return;
1521 else if (precision > 0) { // add dot if missing (and needed)
1522 str.append(QLatin1Char('.'));
1523 decimalSymbolPos = str.length() - 1;
1524 }
1525 }
1526 // fill up with more than enough zeroes (in case fractional part too short)
1527 str.reserve(str.length() + precision);
1528 for (int i = 0; i < precision; ++i)
1529 str.append(QLatin1Char('0'));
1530
1531 // Now decide whether to round up or down
1532 char last_char = str[decimalSymbolPos + precision + 1].toLatin1();
1533 switch (last_char) {
1534 case '0':
1535 case '1':
1536 case '2':
1537 case '3':
1538 case '4':
1539 // nothing to do, rounding down
1540 break;
1541 case '5':
1542 case '6':
1543 case '7':
1544 case '8':
1545 case '9':
1546 _inc_by_one(str, decimalSymbolPos + precision);
1547 break;
1548 default:
1549 break;
1550 }
1551
1552 decimalSymbolPos = str.indexOf(QLatin1Char('.'));
1553 str.truncate(decimalSymbolPos + precision + 1);
1554
1555 // if precision == 0 delete also '.'
1556 if (precision == 0) {
1557 str = str.left(decimalSymbolPos);
1558 }
1559
1560 str.squeeze();
1561}
1562
1563QString KLocalePrivate::formatNumber(const QString &numStr, bool round, int precision) const
1564{
1565 QString tmpString = numStr;
1566
1567 if (precision < 0) {
1568 precision = decimalPlaces();
1569 }
1570
1571 // Skip the sign (for now)
1572 const bool neg = (tmpString[0] == QLatin1Char('-'));
1573 if (neg || tmpString[0] == QLatin1Char('+')) {
1574 tmpString.remove(0, 1);
1575 }
1576
1577 //kDebug(173)<<"tmpString:"<<tmpString;
1578
1579 // Split off exponential part (including 'e'-symbol)
1580 const int expPos = tmpString.indexOf(QLatin1Char('e')); // -1 if not found
1581 QString mantString = tmpString.left(expPos); // entire string if no 'e' found
1582 QString expString;
1583 if (expPos > -1) {
1584 expString = tmpString.mid(expPos); // includes the 'e', or empty if no 'e'
1585 if (expString.length() == 1) {
1586 expString.clear();
1587 }
1588 }
1589
1590 //kDebug(173)<<"mantString:"<<mantString;
1591 //kDebug(173)<<"expString:"<<expString;
1592 if (mantString.isEmpty() || !mantString[0].isDigit()) {// invalid number
1593 mantString = QLatin1Char('0');
1594 }
1595
1596 if (round) {
1597 _round(mantString, precision);
1598 }
1599
1600 // Replace dot with locale decimal separator
1601 mantString.replace(QLatin1Char('.'), decimalSymbol());
1602
1603 // Insert the thousand separators
1604 mantString = formatDigitGroup(mantString, thousandsSeparator(), decimalSymbol(), numericDigitGrouping());
1605
1606 // How can we know where we should put the sign?
1607 mantString.prepend(neg ? negativeSign() : positiveSign());
1608
1609 // Convert to target digit set.
1610 if (digitSet() != KLocale::ArabicDigits) {
1611 mantString = convertDigits(mantString, digitSet());
1612 expString = convertDigits(expString, digitSet());
1613 }
1614
1615 return mantString + expString;
1616}
1617
1618// Returns a list of already translated units to use later in formatByteSize
1619// and friends. Account for every unit in KLocale::BinarySizeUnits
1620QList<QString> KLocalePrivate::dialectUnitsList(KLocale::BinaryUnitDialect dialect)
1621{
1622 QList<QString> binaryUnits;
1623 QString s; // Used in CACHE_BYTE_FMT macro defined shortly
1624
1625 // Adds a given translation to the binaryUnits list.
1626#define CACHE_BYTE_FMT(ctxt_text) \
1627 translateRawFrom(0, ctxt_text, 0, 0, 0, &s); \
1628 binaryUnits.append(s);
1629
1630 // Do not remove i18n: comments below, they are used by the
1631 // translators.
1632
1633 // This prefix is shared by all current dialects.
1634 // i18n: Dumb message, avoid any markup or scripting.
1635 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in bytes", "%1 B"));
1636
1637 switch (dialect) {
1638 case KLocale::MetricBinaryDialect:
1639 // i18n: Dumb message, avoid any markup or scripting.
1640 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 1000 bytes", "%1 kB"));
1641 // i18n: Dumb message, avoid any markup or scripting.
1642 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 10^6 bytes", "%1 MB"));
1643 // i18n: Dumb message, avoid any markup or scripting.
1644 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 10^9 bytes", "%1 GB"));
1645 // i18n: Dumb message, avoid any markup or scripting.
1646 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 10^12 bytes", "%1 TB"));
1647 // i18n: Dumb message, avoid any markup or scripting.
1648 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 10^15 bytes", "%1 PB"));
1649 // i18n: Dumb message, avoid any markup or scripting.
1650 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 10^18 bytes", "%1 EB"));
1651 // i18n: Dumb message, avoid any markup or scripting.
1652 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 10^21 bytes", "%1 ZB"));
1653 // i18n: Dumb message, avoid any markup or scripting.
1654 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 10^24 bytes", "%1 YB"));
1655 break;
1656
1657 case KLocale::JEDECBinaryDialect:
1658 // i18n: Dumb message, avoid any markup or scripting.
1659 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("memory size in 1024 bytes", "%1 KB"));
1660 // i18n: Dumb message, avoid any markup or scripting.
1661 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("memory size in 2^20 bytes", "%1 MB"));
1662 // i18n: Dumb message, avoid any markup or scripting.
1663 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("memory size in 2^30 bytes", "%1 GB"));
1664 // i18n: Dumb message, avoid any markup or scripting.
1665 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("memory size in 2^40 bytes", "%1 TB"));
1666 // i18n: Dumb message, avoid any markup or scripting.
1667 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("memory size in 2^50 bytes", "%1 PB"));
1668 // i18n: Dumb message, avoid any markup or scripting.
1669 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("memory size in 2^60 bytes", "%1 EB"));
1670 // i18n: Dumb message, avoid any markup or scripting.
1671 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("memory size in 2^70 bytes", "%1 ZB"));
1672 // i18n: Dumb message, avoid any markup or scripting.
1673 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("memory size in 2^80 bytes", "%1 YB"));
1674 break;
1675
1676 case KLocale::IECBinaryDialect:
1677 default:
1678 // i18n: Dumb message, avoid any markup or scripting.
1679 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 1024 bytes", "%1 KiB"));
1680 // i18n: Dumb message, avoid any markup or scripting.
1681 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 2^20 bytes", "%1 MiB"));
1682 // i18n: Dumb message, avoid any markup or scripting.
1683 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 2^30 bytes", "%1 GiB"));
1684 // i18n: Dumb message, avoid any markup or scripting.
1685 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 2^40 bytes", "%1 TiB"));
1686 // i18n: Dumb message, avoid any markup or scripting.
1687 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 2^50 bytes", "%1 PiB"));
1688 // i18n: Dumb message, avoid any markup or scripting.
1689 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 2^60 bytes", "%1 EiB"));
1690 // i18n: Dumb message, avoid any markup or scripting.
1691 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 2^70 bytes", "%1 ZiB"));
1692 // i18n: Dumb message, avoid any markup or scripting.
1693 CACHE_BYTE_FMT(I18N_NOOP2_NOSTRIP("size in 2^80 bytes", "%1 YiB"));
1694 break;
1695 }
1696
1697 return binaryUnits;
1698}
1699
1700QString KLocalePrivate::formatByteSize(double size, int precision, KLocale::BinaryUnitDialect dialect,
1701 KLocale::BinarySizeUnits specificUnit)
1702{
1703 // Error checking
1704 if (dialect <= KLocale::DefaultBinaryDialect || dialect > KLocale::LastBinaryDialect) {
1705 dialect = m_binaryUnitDialect;
1706 }
1707
1708 if (specificUnit < KLocale::DefaultBinaryUnits || specificUnit > KLocale::UnitLastUnit) {
1709 specificUnit = KLocale::DefaultBinaryUnits;
1710 }
1711
1712 // Choose appropriate units.
1713 QList<QString> dialectUnits;
1714 if (dialect == m_binaryUnitDialect) {
1715 // Cache default units for speed
1716 if (m_byteSizeFmt.size() == 0) {
1717 QMutexLocker lock(kLocaleMutex());
1718
1719 // We only cache the user's default dialect.
1720 m_byteSizeFmt = dialectUnitsList(m_binaryUnitDialect);
1721 }
1722
1723 dialectUnits = m_byteSizeFmt;
1724 } else {
1725 dialectUnits = dialectUnitsList(dialect);
1726 }
1727
1728 int unit = 0; // Selects what unit to use from cached list
1729 double multiplier = 1024.0;
1730
1731 if (dialect == KLocale::MetricBinaryDialect) {
1732 multiplier = 1000.0;
1733 }
1734
1735 // If a specific unit conversion is given, use it directly. Otherwise
1736 // search until the result is in [0, multiplier) (or out of our range).
1737 if (specificUnit == KLocale::DefaultBinaryUnits) {
1738 while (qAbs(size) >= multiplier && unit < (int) KLocale::UnitYottaByte) {
1739 size /= multiplier;
1740 unit++;
1741 }
1742 } else {
1743 // A specific unit is in use
1744 unit = static_cast<int>(specificUnit);
1745 if (unit > 0) {
1746 size /= pow(multiplier, unit);
1747 }
1748 }
1749
1750 if (unit == 0) {
1751 // Bytes, no rounding
1752 return dialectUnits[unit].arg(formatNumber(size, 0));
1753 }
1754
1755 return dialectUnits[unit].arg(formatNumber(size, precision));
1756}
1757
1758QString KLocalePrivate::formatByteSize(double size)
1759{
1760 return formatByteSize(size, 1);
1761}
1762
1763KLocale::BinaryUnitDialect KLocalePrivate::binaryUnitDialect() const
1764{
1765 return m_binaryUnitDialect;
1766}
1767
1768void KLocalePrivate::setBinaryUnitDialect(KLocale::BinaryUnitDialect newDialect)
1769{
1770 if (newDialect > KLocale::DefaultBinaryDialect && newDialect <= KLocale::LastBinaryDialect) {
1771 QMutexLocker lock(kLocaleMutex());
1772 m_binaryUnitDialect = newDialect;
1773 m_byteSizeFmt.clear(); // Reset cached translations.
1774 }
1775}
1776
1777QString KLocalePrivate::formatDuration(unsigned long mSec) const
1778{
1779 if (mSec >= 24*3600000) {
1780 return i18nc("@item:intext %1 is a real number, e.g. 1.23 days", "%1 days",
1781 formatNumber(mSec / (24 * 3600000.0), 2));
1782 } else if (mSec >= 3600000) {
1783 return i18nc("@item:intext %1 is a real number, e.g. 1.23 hours", "%1 hours",
1784 formatNumber(mSec / 3600000.0, 2));
1785 } else if (mSec >= 60000) {
1786 return i18nc("@item:intext %1 is a real number, e.g. 1.23 minutes", "%1 minutes",
1787 formatNumber(mSec / 60000.0, 2));
1788 } else if (mSec >= 1000) {
1789 return i18nc("@item:intext %1 is a real number, e.g. 1.23 seconds", "%1 seconds",
1790 formatNumber(mSec / 1000.0, 2));
1791 }
1792 return i18ncp("@item:intext", "%1 millisecond", "%1 milliseconds", mSec);
1793}
1794
1795QString KLocalePrivate::formatSingleDuration(KLocalePrivate::DurationType durationType, int n)
1796{
1797 switch (durationType) {
1798 case KLocalePrivate::DaysDurationType:
1799 return i18ncp("@item:intext", "1 day", "%1 days", n);
1800 case KLocalePrivate::HoursDurationType:
1801 return i18ncp("@item:intext", "1 hour", "%1 hours", n);
1802 case KLocalePrivate::MinutesDurationType:
1803 return i18ncp("@item:intext", "1 minute", "%1 minutes", n);
1804 case KLocalePrivate::SecondsDurationType:
1805 return i18ncp("@item:intext", "1 second", "%1 seconds", n);
1806 }
1807 return QString();
1808}
1809
1810QString KLocalePrivate::prettyFormatDuration(unsigned long mSec) const
1811{
1812 unsigned long ms = mSec;
1813 int days = ms / (24 * 3600000);
1814 ms = ms % (24 * 3600000);
1815 int hours = ms / 3600000;
1816 ms = ms % 3600000;
1817 int minutes = ms / 60000;
1818 ms = ms % 60000;
1819 int seconds = qRound(ms / 1000.0);
1820
1821 // Handle correctly problematic case #1 (look at KLocaleTest::prettyFormatDuration()
1822 // at klocaletest.cpp)
1823 if (seconds == 60) {
1824 return prettyFormatDuration(mSec - ms + 60000);
1825 }
1826
1827 if (days && hours) {
1828 return i18nc("@item:intext days and hours. This uses the previous item:intext messages. If this does not fit the grammar of your language please contact the i18n team to solve the problem",
1829 "%1 and %2", formatSingleDuration(KLocalePrivate::DaysDurationType, days),
1830 formatSingleDuration(KLocalePrivate::HoursDurationType, hours));
1831 } else if (days) {
1832 return formatSingleDuration(KLocalePrivate::DaysDurationType, days);
1833 } else if (hours && minutes) {
1834 return i18nc("@item:intext hours and minutes. This uses the previous item:intext messages. If this does not fit the grammar of your language please contact the i18n team to solve the problem",
1835 "%1 and %2",
1836 formatSingleDuration(KLocalePrivate::HoursDurationType, hours),
1837 formatSingleDuration(KLocalePrivate::MinutesDurationType, minutes));
1838 } else if (hours) {
1839 return formatSingleDuration(KLocalePrivate::HoursDurationType, hours);
1840 } else if (minutes && seconds) {
1841 return i18nc("@item:intext minutes and seconds. This uses the previous item:intext messages. If this does not fit the grammar of your language please contact the i18n team to solve the problem",
1842 "%1 and %2",
1843 formatSingleDuration(KLocalePrivate::MinutesDurationType, minutes),
1844 formatSingleDuration(KLocalePrivate::SecondsDurationType, seconds));
1845 } else if (minutes) {
1846 return formatSingleDuration(KLocalePrivate::MinutesDurationType, minutes);
1847 } else {
1848 return formatSingleDuration(KLocalePrivate::SecondsDurationType, seconds);
1849 }
1850}
1851
1852QString KLocalePrivate::formatDate(const QDate &date, KLocale::DateFormat format)
1853{
1854 return calendar()->formatDate(date, format);
1855}
1856
1857void KLocalePrivate::setMainCatalog(const char *catalog)
1858{
1859 KLocaleStaticData *s = staticData;
1860 s->maincatalog = QString::fromUtf8(catalog);
1861}
1862
1863double KLocalePrivate::readNumber(const QString &_str, bool * ok) const
1864{
1865 QString str = _str.trimmed();
1866 bool neg = false;
1867
1868 // Check negative or positive signs
1869 // Assumes blank sign is positive even if pos sign set, unless already taken by negative
1870 if (!negativeSign().isEmpty() && str.indexOf(negativeSign()) == 0) {
1871 neg = true;
1872 str.remove(0, negativeSign().length());
1873 str = str.trimmed();
1874 } else if (!positiveSign().isEmpty() && str.indexOf(positiveSign()) == 0) {
1875 neg = false;
1876 str.remove(0, positiveSign().length());
1877 str = str.trimmed();
1878 } else if (negativeSign().isEmpty() && str[0].isDigit()) {
1879 neg = true;
1880 }
1881
1882 /* will hold the scientific notation portion of the number.
1883 Example, with 2.34E+23, exponentialPart == "E+23"
1884 */
1885 QString exponentialPart;
1886 int EPos;
1887
1888 EPos = str.indexOf(QLatin1Char('E'), 0, Qt::CaseInsensitive);
1889
1890 if (EPos != -1) {
1891 exponentialPart = str.mid(EPos);
1892 str = str.left(EPos);
1893 str = str.trimmed();
1894 }
1895
1896 // Remove group separators
1897 bool groupOk = true;
1898 if(str.contains(thousandsSeparator())) {
1899 str = parseDigitGroup(str, thousandsSeparator(), decimalSymbol(),
1900 numericDigitGrouping(), &groupOk);
1901 }
1902
1903 if (!groupOk) {
1904 if (ok) {
1905 *ok = false;
1906 }
1907 return 0.0;
1908 }
1909
1910 int pos = str.indexOf(decimalSymbol());
1911 QString major;
1912 QString minor;
1913 if (pos == -1) {
1914 major = str;
1915 } else {
1916 major = str.left(pos);
1917 minor = str.mid(pos + decimalSymbol().length());
1918 }
1919
1920 // Check the major and minor parts are only digits
1921 bool digitTest = true;
1922 foreach (const QChar &ch, major) {
1923 if (!ch.isDigit()) {
1924 digitTest = false;
1925 break;
1926 }
1927 }
1928 foreach (const QChar &ch, minor) {
1929 if (!ch.isDigit()) {
1930 digitTest = false;
1931 break;
1932 }
1933 }
1934 if (!digitTest) {
1935 if (ok) {
1936 *ok = false;
1937 }
1938 return 0.0;
1939 }
1940
1941 QString tot;
1942 if (neg) {
1943 tot = QLatin1Char('-');
1944 }
1945 tot += major + QLatin1Char('.') + minor + exponentialPart;
1946 tot = toArabicDigits(tot);
1947 return tot.toDouble(ok);
1948}
1949
1950double KLocalePrivate::readMoney(const QString &_str, bool *ok) const
1951{
1952 QString str = _str.trimmed();
1953 bool neg = false;
1954 bool currencyFound = false;
1955 QString symbol = currencySymbol();
1956
1957 // First try removing currency symbol from either end
1958 int pos = str.indexOf(symbol);
1959 if (pos == 0 || pos == (int) str.length() - symbol.length()) {
1960 str.remove(pos, symbol.length());
1961 str = str.trimmed();
1962 currencyFound = true;
1963 }
1964 if (str.isEmpty()) {
1965 if (ok) {
1966 *ok = false;
1967 }
1968 return 0;
1969 }
1970
1971 // Then try removing sign from either end (with a special case for parenthesis)
1972 if (str[0] == QLatin1Char('(') && str[str.length()-1] == QLatin1Char(')')) {
1973 if (positiveMonetarySignPosition() != KLocale::ParensAround) {
1974 neg = true;
1975 }
1976 str.remove(str.length() - 1, 1);
1977 str.remove(0, 1);
1978 str = str.trimmed();
1979 } else {
1980 int len = 0;
1981 QString sign;
1982 int negLen = negativeSign().length();
1983 QString negSign = negativeSign();
1984 if (!negSign.isEmpty() && (str.left(negLen) == negSign || str.right(negSign.length()) == negSign)) {
1985 neg = true;
1986 len = negLen;
1987 sign = negSign;
1988 } else {
1989 int posLen = positiveSign().length();
1990 QString posSign = positiveSign();
1991 if (!posSign.isEmpty() && (str.left(posLen) == posSign || str.right(posSign.length()) == posSign)) {
1992 len = posLen;
1993 sign = posSign;
1994 } else if (negSign.isEmpty() && str[0].isDigit() && str[str.length() - 1].isDigit()){
1995 neg = true;
1996 }
1997 }
1998 if (!sign.isEmpty()) {
1999 if (str.left(len) == sign) {
2000 str.remove(0, len);
2001 } else {
2002 str.remove(str.length() - len, len);
2003 }
2004 str = str.trimmed();
2005 }
2006 }
2007
2008 // Finally try again for the currency symbol, if we didn't find
2009 // it already (because of the negative sign being in the way).
2010 if (!currencyFound) {
2011 pos = str.indexOf(symbol);
2012 if (pos == 0 || pos == (int) str.length() - symbol.length()) {
2013 str.remove(pos, symbol.length());
2014 str = str.trimmed();
2015 }
2016 }
2017
2018 // Remove group separators
2019 bool groupOk = true;
2020 if(str.contains(monetaryThousandsSeparator())) {
2021 str = parseDigitGroup(str, monetaryThousandsSeparator(), monetaryDecimalSymbol(),
2022 monetaryDigitGrouping(), &groupOk);
2023 }
2024
2025 if (!groupOk) {
2026 if (ok) {
2027 *ok = false;
2028 }
2029 return 0.0;
2030 }
2031
2032 // And parse the rest as a number
2033 pos = str.indexOf(monetaryDecimalSymbol());
2034 QString major;
2035 QString minor;
2036 if (pos == -1) {
2037 major = str;
2038 } else {
2039 major = str.left(pos);
2040 minor = str.mid(pos + monetaryDecimalSymbol().length());
2041 }
2042
2043 // Check the major and minor parts are only digits
2044 bool digitTest = true;
2045 foreach (const QChar &ch, major) {
2046 if (!ch.isDigit()) {
2047 digitTest = false;
2048 break;
2049 }
2050 }
2051 foreach (const QChar &ch, minor) {
2052 if (!ch.isDigit()) {
2053 digitTest = false;
2054 break;
2055 }
2056 }
2057 if (!digitTest) {
2058 if (ok) {
2059 *ok = false;
2060 }
2061 return 0.0;
2062 }
2063
2064 QString tot;
2065 if (neg) {
2066 tot = QLatin1Char('-');
2067 }
2068 tot += major + QLatin1Char('.') + minor;
2069 tot = toArabicDigits(tot);
2070 return tot.toDouble(ok);
2071}
2072
2079static int readInt(const QString &str, int &pos)
2080{
2081 if (!str.at(pos).isDigit()) {
2082 return -1;
2083 }
2084 int result = 0;
2085 for (; str.length() > pos && str.at(pos).isDigit(); ++pos) {
2086 result *= 10;
2087 result += str.at(pos).digitValue();
2088 }
2089
2090 return result;
2091}
2092
2093QDate KLocalePrivate::readDate(const QString &intstr, bool *ok)
2094{
2095 return calendar()->readDate(intstr, ok);
2096}
2097
2098QDate KLocalePrivate::readDate(const QString &intstr, KLocale::ReadDateFlags flags, bool *ok)
2099{
2100 return calendar()->readDate(intstr, flags, ok);
2101}
2102
2103QDate KLocalePrivate::readDate(const QString &intstr, const QString &fmt, bool *ok)
2104{
2105 return calendar()->readDate(intstr, fmt, ok);
2106}
2107
2108QTime KLocalePrivate::readTime(const QString &intstr, bool *ok) const
2109{
2110 QTime time = readLocaleTime(intstr, ok, KLocale::TimeDefault, KLocale::ProcessStrict);
2111 if (time.isValid()) {
2112 return time;
2113 }
2114 return readLocaleTime(intstr, ok, KLocale::TimeWithoutSeconds, KLocale::ProcessStrict);
2115}
2116
2117QTime KLocalePrivate::readTime(const QString &intstr, KLocale::ReadTimeFlags flags, bool *ok) const
2118{
2119 return readLocaleTime(intstr, ok, (flags == KLocale::WithSeconds) ? KLocale::TimeDefault : KLocale::TimeWithoutSeconds,
2120 KLocale::ProcessStrict);
2121}
2122
2123// remove the first occurrence of the 2-character string
2124// strip2char from inout and if found, also remove one preceding
2125// punctuation character and arbitrary number of spaces.
2126static void stripStringAndPreceedingSeparator(QString &inout, const QLatin1String &strip2char)
2127{
2128 int remPos = inout.indexOf(strip2char);
2129 if (remPos == -1) {
2130 return;
2131 }
2132 int endPos = remPos + 2;
2133 int curPos = remPos - 1;
2134 while (curPos >= 0 && inout.at(curPos).isSpace()) {
2135 curPos--;
2136 }
2137 // remove the separator sign before the seconds
2138 // and assume that works everywhere
2139 if (curPos >= 0 && inout.at(curPos).isPunct() && inout.at(curPos) != QLatin1Char('%')) {
2140 curPos--;
2141 }
2142 while (curPos >= 0 && inout.at(curPos).isSpace()) {
2143 curPos--;
2144 }
2145
2146 remPos = qMax(curPos + 1, 0);
2147 inout.remove(remPos, endPos - remPos);
2148}
2149
2150// remove the first occurrence of the 2-character string
2151// strip2char from inout and if found, also remove one
2152// succeeding punctuation character and arbitrary number of spaces.
2153static void stripStringAndSucceedingSeparator(QString &inout, const QLatin1String &strip2char)
2154{
2155 int remPos = inout.indexOf(strip2char);
2156 if (remPos == -1) {
2157 return;
2158 }
2159 int curPos = remPos + 2;
2160 while (curPos < inout.size() &&
2161 (inout.at(curPos).isSpace() ||
2162 (inout.at(curPos).isPunct() && inout.at(curPos) != QLatin1Char('%')))) {
2163 curPos++;
2164 }
2165 inout.remove(remPos, curPos - remPos);
2166}
2167
2168// remove the first occurrence of "%p" from the inout.
2169static void stripAmPmFormat(QString &inout)
2170{
2171 // NOTE: this function assumes that %p - if it's present -
2172 // is either the first or the last element of the format
2173 // string. Either a succeeding or a preceding
2174 // punctuation symbol is stripped.
2175 int length = inout.size();
2176 int ppos = inout.indexOf(QLatin1String("%p"));
2177 if (ppos == -1) {
2178 return;
2179 } else if (ppos == 0) {
2180 // first element, eat succeeding punctuation and spaces
2181 ppos = 2;
2182 while (ppos < length && (inout.at(ppos).isSpace() || inout.at(ppos).isPunct()) &&
2183 inout.at(ppos) != QLatin1Char('%')) {
2184 ppos++;
2185 }
2186 inout = inout.mid(ppos);
2187 } else {
2188 stripStringAndPreceedingSeparator(inout, QLatin1String("%p"));
2189 }
2190}
2191
2192QTime KLocalePrivate::readLocaleTime(const QString &intstr, bool *ok, KLocale::TimeFormatOptions options,
2193 KLocale::TimeProcessingOptions processing) const
2194{
2195 QString str(intstr.simplified().toLower());
2196 QString format(timeFormat().simplified());
2197
2198 int hour = -1;
2199 int minute = -1;
2200 int second = -1;
2201 bool useDayPeriod = false;
2202 KDayPeriod dayPeriod = dayPeriodForTime(QTime(0,0,0));
2203 int strpos = 0;
2204 int formatpos = 0;
2205 bool error = false;
2206
2207 bool excludeSecs = ((options & KLocale::TimeWithoutSeconds) == KLocale::TimeWithoutSeconds);
2208 bool isDuration = ((options & KLocale::TimeDuration) == KLocale::TimeDuration);
2209 bool noAmPm = ((options & KLocale::TimeWithoutAmPm) == KLocale::TimeWithoutAmPm);
2210 bool foldHours = ((options & KLocale::TimeFoldHours) == KLocale::TimeFoldHours);
2211 bool strict = ((processing & KLocale::ProcessStrict) == KLocale::ProcessStrict);
2212
2213 // if seconds aren't needed, strip them from the timeFormat
2214 if (excludeSecs) {
2215 stripStringAndPreceedingSeparator(format, QLatin1String("%S"));
2216 second = 0; // seconds are always 0
2217 }
2218
2219 // if hours are folded, strip them from the timeFormat
2220 if (foldHours) {
2221 stripStringAndSucceedingSeparator(format, QLatin1String("%H"));
2222 stripStringAndSucceedingSeparator(format, QLatin1String("%k"));
2223 stripStringAndSucceedingSeparator(format, QLatin1String("%I"));
2224 stripStringAndSucceedingSeparator(format, QLatin1String("%l"));
2225 }
2226
2227 // if am/pm isn't needed, strip it from the timeFormat
2228 if (noAmPm) {
2229 stripAmPmFormat(format);
2230 }
2231
2232 while (!error && (format.length() > formatpos || str.length() > strpos)) {
2233 if (!(format.length() > formatpos && str.length() > strpos)) {
2234 error = true;
2235 break;
2236 }
2237
2238 QChar c = format.at(formatpos++);
2239 if (c.isSpace()) {
2240 if (strict) { // strict processing: space is needed
2241 if (!str.at(strpos).isSpace()) {
2242 error = true;
2243 break;
2244 }
2245 strpos++;
2246 } else { // lax processing: space in str not needed
2247 // 1 space maximum as str is simplified
2248 if (str.at(strpos).isSpace()) {
2249 strpos++;
2250 }
2251 }
2252 continue;
2253 }
2254
2255 if (c != QLatin1Char('%')) {
2256 if (c != str.at(strpos++)) {
2257 error = true;
2258 break;
2259 }
2260 continue;
2261 }
2262
2263 c = format.at(formatpos++);
2264 switch (c.unicode()) {
2265
2266 case 'p': // Day Period, normally AM/PM
2267 case 'P': // Lowercase Day Period, normally am/pm
2268 {
2269 error = true;
2270 foreach (const KDayPeriod &testDayPeriod, dayPeriods()) {
2271 QString dayPeriodText = testDayPeriod.periodName(KLocale::ShortName);
2272 int len = dayPeriodText.length();
2273 if (str.mid(strpos, len) == dayPeriodText.toLower()) {
2274 dayPeriod = testDayPeriod;
2275 strpos += len;
2276 error = false;
2277 useDayPeriod = true;
2278 break;
2279 }
2280 }
2281 break;
2282 }
2283
2284 case 'k': // 24h Hours Short Number
2285 case 'H': // 24h Hours Long Number
2286 useDayPeriod = false;
2287 hour = readInt(str, strpos);
2288 break;
2289
2290 case 'l': // 12h Hours Short Number
2291 case 'I': // 12h Hours Long Number
2292 useDayPeriod = !isDuration;
2293 hour = readInt(str, strpos);
2294 break;
2295
2296 case 'M':
2297 minute = readInt(str, strpos);
2298 // minutes can be bigger than 59 if hours are folded
2299 if (foldHours) {
2300 // if hours are folded, make sure minutes doesn't get bigger than 59.
2301 hour = minute / 60;
2302 minute = minute % 60;
2303 }
2304 break;
2305
2306 case 'S':
2307 second = readInt(str, strpos);
2308 break;
2309 }
2310
2311 // NOTE: if anything is performed inside this loop, be sure to
2312 // check for error!
2313 }
2314
2315 QTime returnTime;
2316 if (!error) {
2317 if (useDayPeriod) {
2318 returnTime = dayPeriod.time(hour, minute, second);
2319 } else {
2320 returnTime = QTime(hour, minute, second);
2321 }
2322 }
2323 if (ok) {
2324 *ok = returnTime.isValid();
2325 }
2326 return returnTime;
2327}
2328
2329QString KLocalePrivate::formatTime(const QTime &time, bool includeSecs, bool isDuration) const
2330{
2331 KLocale::TimeFormatOptions options = KLocale::TimeDefault;
2332 if (!includeSecs) {
2333 options |= KLocale::TimeWithoutSeconds;
2334 }
2335 if (isDuration) {
2336 options |= KLocale::TimeDuration;
2337 }
2338 return formatLocaleTime(time, options);
2339}
2340
2341QString KLocalePrivate::formatLocaleTime(const QTime &time, KLocale::TimeFormatOptions options) const
2342{
2343 QString rst(timeFormat());
2344
2345 bool excludeSecs = ((options & KLocale::TimeWithoutSeconds) == KLocale::TimeWithoutSeconds);
2346 bool isDuration = ((options & KLocale::TimeDuration) == KLocale::TimeDuration);
2347 bool noAmPm = ((options & KLocale::TimeWithoutAmPm) == KLocale::TimeWithoutAmPm);
2348 bool foldHours = ((options & KLocale::TimeFoldHours) == KLocale::TimeFoldHours);
2349
2350 // if seconds aren't needed, strip them from the timeFormat
2351 if (excludeSecs) {
2352 stripStringAndPreceedingSeparator(rst, QLatin1String("%S"));
2353 }
2354
2355 // if hours should be folded, strip all hour symbols from the timeFormat
2356 if (foldHours) {
2357 stripStringAndSucceedingSeparator(rst, QLatin1String("%H"));
2358 stripStringAndSucceedingSeparator(rst, QLatin1String("%k"));
2359 stripStringAndSucceedingSeparator(rst, QLatin1String("%I"));
2360 stripStringAndSucceedingSeparator(rst, QLatin1String("%l"));
2361 }
2362
2363 // if am/pm isn't needed, strip it from the timeFormat
2364 if (noAmPm) {
2365 stripAmPmFormat(rst);
2366 }
2367
2368 // only "pm/am" and %M here can grow, the rest shrinks, but
2369 // I'm rather safe than sorry
2370 QChar *buffer = new QChar[rst.length() * 3 / 2 + 32];
2371
2372 int index = 0;
2373 bool escape = false;
2374 int number = 0;
2375
2376 for (int format_index = 0; format_index < rst.length(); format_index++) {
2377 if (!escape) {
2378 if (rst.at(format_index).unicode() == '%') {
2379 escape = true;
2380 } else {
2381 buffer[index++] = rst.at(format_index);
2382 }
2383 } else {
2384 switch (rst.at(format_index).unicode()) {
2385 case '%':
2386 buffer[index++] = QLatin1Char('%');
2387 break;
2388 case 'H':
2389 put_it_in(buffer, index, time.hour());
2390 break;
2391 case 'I':
2392 if (isDuration) {
2393 put_it_in(buffer, index, time.hour());
2394 } else {
2395 put_it_in(buffer, index, dayPeriodForTime(time).hourInPeriod(time));
2396 }
2397 break;
2398 case 'M':
2399 if (foldHours) {
2400 put_it_in(buffer, index, QString::number(time.hour() * 60 + time.minute()));
2401 } else {
2402 put_it_in(buffer, index, time.minute());
2403 }
2404 break;
2405 case 'S':
2406 put_it_in(buffer, index, time.second());
2407 break;
2408 case 'k':
2409 case 'l':
2410 // to share the code
2411 if (!isDuration && rst.at(format_index).unicode() == 'l') {
2412 number = dayPeriodForTime(time).hourInPeriod(time);
2413 } else {
2414 number = time.hour();
2415 }
2416 if (number / 10) {
2417 buffer[index++] = number / 10 + '0';
2418 }
2419 buffer[index++] = number % 10 + '0';
2420 break;
2421 case 'p':
2422 {
2423 put_it_in(buffer, index, dayPeriodForTime(time).periodName(KLocale::ShortName));
2424 break;
2425 }
2426 default:
2427 buffer[index++] = rst.at(format_index);
2428 break;
2429 }
2430 escape = false;
2431 }
2432 }
2433 QString ret(buffer, index);
2434 delete [] buffer;
2435 ret = convertDigits(ret, dateTimeDigitSet());
2436 return ret.trimmed();
2437}
2438
2439bool KLocalePrivate::use12Clock() const
2440{
2441 if ((timeFormat().contains(QString::fromLatin1("%I")) != 0) ||
2442 (timeFormat().contains(QString::fromLatin1("%l")) != 0)) {
2443 return true;
2444 } else {
2445 return false;
2446 }
2447}
2448
2449void KLocalePrivate::setDayPeriods(const QList<KDayPeriod> &dayPeriods)
2450{
2451 if (dayPeriods.count() > 0) {
2452 foreach (const KDayPeriod &dayPeriod, dayPeriods) {
2453 if (!dayPeriod.isValid()) {
2454 return;
2455 }
2456 }
2457 m_dayPeriods = dayPeriods;
2458 }
2459}
2460
2461QList<KDayPeriod> KLocalePrivate::dayPeriods() const
2462{
2463 // If no Day Periods currently loaded then it means there were no country specific ones defined
2464 // in the country l10n file, so default to standard AM/PM translations for the users language.
2465 // Note we couldn't do this in initDayPeriods() as i18n isn't available until we have a
2466 // valid loacle constructed.
2467 if (m_dayPeriods.isEmpty()) {
2468 m_dayPeriods.append(KDayPeriod(QString::fromLatin1("am"),
2469 i18nc( "Before Noon KLocale::LongName", "Ante Meridiem" ),
2470 i18nc( "Before Noon KLocale::ShortName", "AM" ),
2471 i18nc( "Before Noon KLocale::NarrowName", "A" ),
2472 QTime( 0, 0, 0 ), QTime( 11, 59, 59, 999 ), 0, 12 ));
2473 m_dayPeriods.append(KDayPeriod(QString::fromLatin1("pm"),
2474 i18nc( "After Noon KLocale::LongName", "Post Meridiem" ),
2475 i18nc( "After Noon KLocale::ShortName", "PM" ),
2476 i18nc( "After Noon KLocale::NarrowName", "P" ),
2477 QTime( 12, 0, 0 ), QTime( 23, 59, 59, 999 ), 0, 12 ));
2478 }
2479 return m_dayPeriods;
2480}
2481
2482KDayPeriod KLocalePrivate::dayPeriodForTime(const QTime &time) const
2483{
2484 if (time.isValid()) {
2485 foreach (const KDayPeriod &dayPeriod, dayPeriods()) {
2486 if (dayPeriod.isValid(time)) {
2487 return dayPeriod;
2488 }
2489 }
2490 }
2491 return KDayPeriod();
2492}
2493
2494QStringList KLocalePrivate::languageList() const
2495{
2496 return m_languageList;
2497}
2498
2499QStringList KLocalePrivate::currencyCodeList() const
2500{
2501 return m_currencyCodeList;
2502}
2503
2504QString KLocalePrivate::formatDateTime(const KLocale *locale, const QDateTime &dateTime, KLocale::DateFormat format,
2505 bool includeSeconds, int daysTo, int secsTo)
2506{
2507 // Have to do Fancy Date formatting here rather than using normal KCalendarSystem::formatDate()
2508 // as daysTo is relative to the time spec which formatDate doesn't know about. Needs to be
2509 // kept in sync with Fancy Date code in KCalendarSystem::formatDate(). Fix in KDE5.
2510
2511 // Only do Fancy if less than an hour into the future or less than a week in the past
2512 if ((daysTo == 0 && secsTo > 3600) || daysTo < 0 || daysTo > 6) {
2513 if (format == KLocale::FancyShortDate) {
2514 format = KLocale::ShortDate;
2515 } else if (format == KLocale::FancyLongDate) {
2516 format = KLocale::LongDate;
2517 }
2518 }
2519
2520 QString dateStr;
2521 if (format == KLocale::FancyShortDate || format == KLocale::FancyLongDate) {
2522 switch (daysTo) {
2523 case 0:
2524 dateStr = i18n("Today");
2525 break;
2526 case 1:
2527 dateStr = i18n("Yesterday");
2528 break;
2529 default:
2530 dateStr = locale->calendar()->weekDayName(dateTime.date());
2531 }
2532 } else {
2533 dateStr = locale->formatDate(dateTime.date(), format);
2534 }
2535
2536 KLocale::TimeFormatOption timeFormat;
2537 if (includeSeconds) {
2538 timeFormat = KLocale::TimeDefault;
2539 } else {
2540 timeFormat = KLocale::TimeWithoutSeconds;
2541 }
2542
2543 return i18nc("concatenation of dates and time", "%1 %2", dateStr,
2544 locale->formatLocaleTime(dateTime.time(), timeFormat));
2545}
2546
2547QString KLocalePrivate::formatDateTime(const QDateTime &dateTime, KLocale::DateFormat format, bool includeSeconds) const
2548{
2549 QDateTime now = QDateTime::currentDateTime();
2550 int daysTo = dateTime.date().daysTo(now.date());
2551 int secsTo = now.secsTo(dateTime);
2552 return KLocalePrivate::formatDateTime(q, dateTime, format, includeSeconds, daysTo, secsTo);
2553}
2554
2555QString KLocalePrivate::formatDateTime(const KDateTime &dateTime, KLocale::DateFormat format,
2556 KLocale::DateTimeFormatOptions options)
2557{
2558 QString dt;
2559
2560 if (dateTime.isDateOnly()) {
2561 dt = formatDate(dateTime.date(), format);
2562 } else {
2563 KDateTime now = KDateTime::currentDateTime(dateTime.timeSpec());
2564 int daysTo = dateTime.date().daysTo(now.date());
2565 int secsTo = now.secsTo(dateTime);
2566 dt = KLocalePrivate::formatDateTime(q, dateTime.dateTime(), format, (options & KLocale::Seconds), daysTo, secsTo);
2567 }
2568
2569 if (options & KLocale::TimeZone) {
2570 QString tz;
2571 switch (dateTime.timeType()) {
2572 case KDateTime::OffsetFromUTC:
2573 tz = i18n(dateTime.toString(QString::fromLatin1("%z")).toUtf8());
2574 break;
2575 case KDateTime::UTC:
2576 case KDateTime::TimeZone:
2577 tz = i18n(dateTime.toString(QString::fromLatin1((format == KLocale::ShortDate) ? "%Z" : "%:Z")).toUtf8());
2578 break;
2579 case KDateTime::ClockTime:
2580 default:
2581 break;
2582 }
2583 return i18nc("concatenation of date/time and time zone", "%1 %2", dt, tz);
2584 }
2585
2586 return dt;
2587}
2588
2589QString KLocalePrivate::langLookup(const QString &fname, const char *rtype)
2590{
2591 QStringList search;
2592
2593 // assemble the local search paths
2594 const QStringList localDoc = KGlobal::dirs()->resourceDirs(rtype);
2595
2596 // look up the different languages
2597 for (int id = localDoc.count() - 1; id >= 0; --id) {
2598 QStringList langs = KGlobal::locale()->languageList();
2599 // FIXME: KDE 4.5, change such that English is not assumed.
2600 langs.replaceInStrings(QLatin1String("en_US"), QLatin1String("en"));
2601 langs.append(QLatin1String("en"));
2602 Q_FOREACH(const QString &lang, langs)
2603 search.append(QString::fromLatin1("%1%2/%3").arg(localDoc[id]).arg(lang).arg(fname));
2604 }
2605
2606 // try to locate the file
2607 Q_FOREACH(const QString &file, search) {
2608 kDebug(173) << "Looking for help in: " << file;
2609
2610 QFileInfo info(file);
2611 if (info.exists() && info.isFile() && info.isReadable())
2612 return file;
2613 }
2614
2615 return QString();
2616}
2617
2618bool KLocalePrivate::useDefaultLanguage() const
2619{
2620 return language() == KLocale::defaultLanguage();
2621}
2622
2623void KLocalePrivate::initEncoding()
2624{
2625 m_codecForEncoding = 0;
2626
2627 // This all made more sense when we still had the EncodingEnum config key.
2628
2629 QByteArray codeset = systemCodeset();
2630
2631 if (!codeset.isEmpty()) {
2632 QTextCodec* codec = QTextCodec::codecForName(codeset);
2633 if (codec) {
2634 setEncoding(codec->mibEnum());
2635 }
2636 } else {
2637 setEncoding(QTextCodec::codecForLocale()->mibEnum());
2638 }
2639
2640 if (!m_codecForEncoding) {
2641 kWarning() << "Cannot resolve system encoding, defaulting to ISO 8859-1.";
2642 const int mibDefault = 4; // ISO 8859-1
2643 setEncoding(mibDefault);
2644 }
2645
2646 Q_ASSERT(m_codecForEncoding);
2647}
2648
2649QByteArray KLocalePrivate::systemCodeset() const
2650{
2651 QByteArray codeset;
2652#if HAVE_LANGINFO_H
2653 // Qt since 4.2 always returns 'System' as codecForLocale and KDE (for example
2654 // KEncodingFileDialog) expects real encoding name. So on systems that have langinfo.h use
2655 // nl_langinfo instead, just like Qt compiled without iconv does. Windows already has its own
2656 // workaround
2657
2658 codeset = nl_langinfo(CODESET);
2659
2660 if ((codeset == "ANSI_X3.4-1968") || (codeset == "US-ASCII")) {
2661 // means ascii, "C"; QTextCodec doesn't know, so avoid warning
2662 codeset = "ISO-8859-1";
2663 }
2664#endif
2665 return codeset;
2666}
2667
2668void KLocalePrivate::initFileNameEncoding()
2669{
2670 // If the following environment variable is set, assume all filenames
2671 // are in UTF-8 regardless of the current C locale.
2672 m_utf8FileEncoding = !qgetenv("KDE_UTF8_FILENAMES").isEmpty();
2673 if (m_utf8FileEncoding) {
2674 QFile::setEncodingFunction(KLocalePrivate::encodeFileNameUTF8);
2675 QFile::setDecodingFunction(KLocalePrivate::decodeFileNameUTF8);
2676 } else {
2677 const QByteArray ctype = setlocale(LC_CTYPE, 0);
2678 int indexOfDot = ctype.indexOf('.');
2679 if (indexOfDot != -1) {
2680 if (!qstrnicmp(ctype.data() + indexOfDot + 1, "UTF-8", 5)) {
2681 QFile::setEncodingFunction(KLocalePrivate::encodeFileNameUTF8);
2682 QFile::setDecodingFunction(KLocalePrivate::decodeFileNameUTF8);
2683 m_utf8FileEncoding = true;
2684 }
2685 return;
2686 }
2687 QByteArray lang = qgetenv("LC_ALL");
2688 if (lang.isEmpty() || lang == "C") {
2689 lang = qgetenv("LC_CTYPE");
2690 }
2691 if (lang.isEmpty() || lang == "C") {
2692 lang = qgetenv("LANG");
2693 }
2694 indexOfDot = lang.indexOf('.');
2695 if (indexOfDot != -1) {
2696 if (!qstrnicmp(lang.data() + indexOfDot + 1, "UTF-8", 5)) {
2697 QFile::setEncodingFunction(KLocalePrivate::encodeFileNameUTF8);
2698 QFile::setDecodingFunction(KLocalePrivate::decodeFileNameUTF8);
2699 m_utf8FileEncoding = true;
2700 }
2701 }
2702 }
2703 // Otherwise, stay with QFile's default filename encoding functions
2704 // which, on Unix platforms, use the locale's codec.
2705}
2706
2707static inline bool isUnicodeNonCharacter(uint ucs4)
2708{
2709 return (ucs4 & 0xfffe) == 0xfffe || (ucs4 - 0xfdd0U) < 16;
2710}
2711
2712QByteArray KLocalePrivate::encodeFileNameUTF8(const QString & fileName)
2713{
2714 if (fileName.isNull()) return QByteArray();
2715 int len = fileName.length();
2716 const QChar *uc = fileName.constData();
2717
2718 uchar replacement = '?';
2719 int rlen = 3*len;
2720 int surrogate_high = -1;
2721
2722 QByteArray rstr;
2723 rstr.resize(rlen);
2724 uchar* cursor = (uchar*)rstr.data();
2725 const QChar *ch = uc;
2726 int invalid = 0;
2727
2728 const QChar *end = ch + len;
2729 while (ch < end) {
2730 uint u = ch->unicode();
2731 if (surrogate_high >= 0) {
2732 if (ch->isLowSurrogate()) {
2733 u = QChar::surrogateToUcs4(surrogate_high, u);
2734 surrogate_high = -1;
2735 } else {
2736 // high surrogate without low
2737 *cursor = replacement;
2738 ++ch;
2739 ++invalid;
2740 surrogate_high = -1;
2741 continue;
2742 }
2743 } else if (ch->isLowSurrogate()) {
2744 // low surrogate without high
2745 *cursor = replacement;
2746 ++ch;
2747 ++invalid;
2748 continue;
2749 } else if (ch->isHighSurrogate()) {
2750 surrogate_high = u;
2751 ++ch;
2752 continue;
2753 }
2754
2755 if (u >= 0x10FE00 && u <= 0x10FE7F) {
2756 *cursor++ = (uchar)(u - 0x10FE00 + 128) ;
2757 }
2758 else if (u < 0x80) {
2759 *cursor++ = (uchar)u;
2760 } else {
2761 if (u < 0x0800) {
2762 *cursor++ = 0xc0 | ((uchar) (u >> 6));
2763 } else {
2764 // is it one of the Unicode non-characters?
2765 if (isUnicodeNonCharacter(u)) {
2766 *cursor++ = replacement;
2767 ++ch;
2768 ++invalid;
2769 continue;
2770 }
2771
2772 if (u > 0xffff) {
2773 *cursor++ = 0xf0 | ((uchar) (u >> 18));
2774 *cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f);
2775 } else {
2776 *cursor++ = 0xe0 | (((uchar) (u >> 12)) & 0x3f);
2777 }
2778 *cursor++ = 0x80 | (((uchar) (u >> 6)) & 0x3f);
2779 }
2780 *cursor++ = 0x80 | ((uchar) (u&0x3f));
2781 }
2782 ++ch;
2783 }
2784
2785 rstr.resize(cursor - (const uchar*)rstr.constData());
2786 return rstr;
2787}
2788
2789QString KLocalePrivate::decodeFileNameUTF8(const QByteArray &localFileName)
2790{
2791 const char *chars = localFileName;
2792 int len = qstrlen(chars);
2793 int need = 0;
2794 uint uc = 0;
2795 uint min_uc = 0;
2796
2797 QString result(2 * (len + 1), Qt::Uninitialized); // worst case
2798 ushort *qch = (ushort *)result.unicode();
2799 uchar ch;
2800
2801 for (int i = 0; i < len; ++i) {
2802 ch = chars[i];
2803 if (need) {
2804 if ((ch&0xc0) == 0x80) {
2805 uc = (uc << 6) | (ch & 0x3f);
2806 --need;
2807 if (!need) {
2808 bool nonCharacter;
2809 if (!(nonCharacter = isUnicodeNonCharacter(uc)) && uc > 0xffff && uc < 0x110000) {
2810 // surrogate pair
2811 Q_ASSERT((qch - (ushort*)result.unicode()) + 2 < result.length());
2812 *qch++ = QChar::highSurrogate(uc);
2813 *qch++ = QChar::lowSurrogate(uc);
2814 } else if ((uc < min_uc) || (uc >= 0xd800 && uc <= 0xdfff) || nonCharacter || uc >= 0x110000) {
2815 // error: overlong sequence, UTF16 surrogate or non-character
2816 goto error;
2817 } else {
2818 *qch++ = uc;
2819 }
2820 }
2821 } else {
2822 goto error;
2823 }
2824 } else {
2825 if (ch < 128) {
2826 *qch++ = ushort(ch);
2827 } else if ((ch & 0xe0) == 0xc0) {
2828 uc = ch & 0x1f;
2829 need = 1;
2830 min_uc = 0x80;
2831 } else if ((ch & 0xf0) == 0xe0) {
2832 uc = ch & 0x0f;
2833 need = 2;
2834 min_uc = 0x800;
2835 } else if ((ch&0xf8) == 0xf0) {
2836 uc = ch & 0x07;
2837 need = 3;
2838 min_uc = 0x10000;
2839 } else {
2840 goto error;
2841 }
2842 }
2843 }
2844 if (need > 0) {
2845 // unterminated UTF sequence
2846 goto error;
2847 }
2848 result.truncate(qch - (ushort *)result.unicode());
2849 return result;
2850
2851error:
2852
2853 qch = (ushort *)result.unicode();
2854 for (int i = 0; i < len; ++i) {
2855 ch = chars[i];
2856 if (ch < 128) {
2857 *qch++ = ushort(ch);
2858 } else {
2859 uint uc = ch - 128 + 0x10FE00; //U+10FE00-U+10FE7F
2860 *qch++ = QChar::highSurrogate(uc);
2861 *qch++ = QChar::lowSurrogate(uc);
2862 }
2863 }
2864 result.truncate(qch - (ushort *)result.unicode());
2865 return result;
2866}
2867
2868void KLocalePrivate::setDateFormat(const QString &format)
2869{
2870 m_dateFormat = format.trimmed();
2871}
2872
2873void KLocalePrivate::setDateFormatShort(const QString &format)
2874{
2875 m_dateFormatShort = format.trimmed();
2876}
2877
2878void KLocalePrivate::setDateMonthNamePossessive(bool possessive)
2879{
2880 m_dateMonthNamePossessive = possessive;
2881}
2882
2883void KLocalePrivate::setTimeFormat(const QString &format)
2884{
2885 m_timeFormat = format.trimmed();
2886}
2887
2888void KLocalePrivate::setWeekStartDay(int day)
2889{
2890 if (day >= 1 && day <= calendar()->daysInWeek(QDate())) {
2891 m_weekStartDay = day;
2892 }
2893}
2894
2895void KLocalePrivate::setWorkingWeekStartDay(int day)
2896{
2897 if (day >= 1 && day <= calendar()->daysInWeek(QDate())) {
2898 m_workingWeekStartDay = day;
2899 }
2900}
2901
2902void KLocalePrivate::setWorkingWeekEndDay(int day)
2903{
2904 if (day >= 1 && day <= calendar()->daysInWeek(QDate())) {
2905 m_workingWeekEndDay = day;
2906 }
2907}
2908
2909void KLocalePrivate::setWeekDayOfPray(int day)
2910{
2911 if (day >= 0 && day <= calendar()->daysInWeek(QDate())) { // 0 = None
2912 m_weekDayOfPray = day;
2913 }
2914}
2915
2916QString KLocalePrivate::dateFormat() const
2917{
2918 return m_dateFormat;
2919}
2920
2921QString KLocalePrivate::dateFormatShort() const
2922{
2923 return m_dateFormatShort;
2924}
2925
2926QString KLocalePrivate::timeFormat() const
2927{
2928 return m_timeFormat;
2929}
2930
2931void KLocalePrivate::setDecimalPlaces(int digits)
2932{
2933 m_decimalPlaces = digits;
2934}
2935
2936void KLocalePrivate::setDecimalSymbol(const QString &symbol)
2937{
2938 m_decimalSymbol = symbol.trimmed();
2939}
2940
2941void KLocalePrivate::setThousandsSeparator(const QString &separator)
2942{
2943 // allow spaces here
2944 m_thousandsSeparator = separator;
2945}
2946
2947void KLocalePrivate::setNumericDigitGrouping(QList<int> groupList)
2948{
2949 m_numericDigitGrouping = groupList;
2950}
2951
2952void KLocalePrivate::setPositiveSign(const QString &sign)
2953{
2954 m_positiveSign = sign.trimmed();
2955}
2956
2957void KLocalePrivate::setNegativeSign(const QString &sign)
2958{
2959 m_negativeSign = sign.trimmed();
2960}
2961
2962void KLocalePrivate::setPositiveMonetarySignPosition(KLocale::SignPosition signpos)
2963{
2964 m_positiveMonetarySignPosition = signpos;
2965}
2966
2967void KLocalePrivate::setNegativeMonetarySignPosition(KLocale::SignPosition signpos)
2968{
2969 m_negativeMonetarySignPosition = signpos;
2970}
2971
2972void KLocalePrivate::setPositivePrefixCurrencySymbol(bool prefix)
2973{
2974 m_positivePrefixCurrencySymbol = prefix;
2975}
2976
2977void KLocalePrivate::setNegativePrefixCurrencySymbol(bool prefix)
2978{
2979 m_negativePrefixCurrencySymbol = prefix;
2980}
2981
2982void KLocalePrivate::setMonetaryDecimalPlaces(int digits)
2983{
2984 m_monetaryDecimalPlaces = digits;
2985}
2986
2987void KLocalePrivate::setMonetaryThousandsSeparator(const QString &separator)
2988{
2989 // allow spaces here
2990 m_monetaryThousandsSeparator = separator;
2991}
2992
2993void KLocalePrivate::setMonetaryDigitGrouping(QList<int> groupList)
2994{
2995 m_monetaryDigitGrouping = groupList;
2996}
2997
2998void KLocalePrivate::setMonetaryDecimalSymbol(const QString &symbol)
2999{
3000 m_monetaryDecimalSymbol = symbol.trimmed();
3001}
3002
3003void KLocalePrivate::setCurrencySymbol(const QString & symbol)
3004{
3005 m_currencySymbol = symbol.trimmed();
3006}
3007
3008int KLocalePrivate::pageSize() const
3009{
3010 return m_pageSize;
3011}
3012
3013void KLocalePrivate::setPageSize(int size)
3014{
3015 // #### check if it's in range??
3016 m_pageSize = size;
3017}
3018
3019KLocale::MeasureSystem KLocalePrivate::measureSystem() const
3020{
3021 return m_measureSystem;
3022}
3023
3024void KLocalePrivate::setMeasureSystem(KLocale::MeasureSystem value)
3025{
3026 m_measureSystem = value;
3027}
3028
3029QString KLocalePrivate::defaultLanguage()
3030{
3031 static const QString en_US = QString::fromLatin1("en_US");
3032 return en_US;
3033}
3034
3035QString KLocalePrivate::defaultCountry()
3036{
3037 return QString::fromLatin1("C");
3038}
3039
3040QString KLocalePrivate::defaultCurrencyCode()
3041{
3042 return QString::fromLatin1("USD");
3043}
3044
3045bool KLocalePrivate::useTranscript() const
3046{
3047 return m_useTranscript;
3048}
3049
3050const QByteArray KLocalePrivate::encoding()
3051{
3052 return codecForEncoding()->name();
3053}
3054
3055int KLocalePrivate::encodingMib() const
3056{
3057 return codecForEncoding()->mibEnum();
3058}
3059
3060int KLocalePrivate::fileEncodingMib() const
3061{
3062 if (m_utf8FileEncoding) {
3063 return 106;
3064 }
3065 return codecForEncoding()->mibEnum();
3066}
3067
3068QTextCodec *KLocalePrivate::codecForEncoding() const
3069{
3070 return m_codecForEncoding;
3071}
3072
3073bool KLocalePrivate::setEncoding(int mibEnum)
3074{
3075 QTextCodec * codec = QTextCodec::codecForMib(mibEnum);
3076 if (codec) {
3077 m_codecForEncoding = codec;
3078 }
3079
3080 return codec != 0;
3081}
3082
3083QStringList KLocalePrivate::allLanguagesList()
3084{
3085 if (!m_languages) {
3086 m_languages = new KConfig(QLatin1String("all_languages"), KConfig::NoGlobals, "locale");
3087 }
3088 return m_languages->groupList();
3089}
3090
3091QStringList KLocalePrivate::installedLanguages()
3092{
3093 QStringList languages;
3094 QStringList paths = KGlobal::dirs()->findAllResources("locale", QLatin1String("*/entry.desktop"));
3095 foreach (const QString &path, paths) {
3096 QString part = path.left(path.length() - 14);
3097 languages.append(part.mid(part.lastIndexOf(QLatin1Char('/')) + 1));
3098 }
3099 languages.sort();
3100 return languages;
3101}
3102
3103QString KLocalePrivate::languageCodeToName(const QString &language)
3104{
3105 if (!m_languages) {
3106 m_languages = new KConfig(QLatin1String("all_languages"), KConfig::NoGlobals, "locale");
3107 }
3108
3109 KConfigGroup cg(m_languages, language);
3110 return cg.readEntry("Name");
3111}
3112
3113QStringList KLocalePrivate::allCountriesList() const
3114{
3115 QStringList countries;
3116 const QStringList paths = KGlobal::dirs()->findAllResources("locale", QLatin1String("l10n/*/entry.desktop"));
3117 for (QStringList::ConstIterator it = paths.begin(); it != paths.end(); ++it) {
3118 QString code = (*it).mid((*it).length() - 16, 2);
3119 if (code != QLatin1String("/C")) {
3120 countries.append(code);
3121 }
3122 }
3123 return countries;
3124}
3125
3126QString KLocalePrivate::countryCodeToName(const QString &country) const
3127{
3128 QString countryName;
3129 QString entryFile = KStandardDirs::locate("locale", QString::fromLatin1("l10n/") + country.toLower() + QLatin1String("/entry.desktop"));
3130 if (!entryFile.isEmpty()) {
3131 KConfig cfg(entryFile);
3132 KConfigGroup cg(&cfg, "KCM Locale");
3133 countryName = cg.readEntry("Name");
3134 }
3135 return countryName;
3136}
3137
3138KLocale::CalendarSystem KLocalePrivate::calendarTypeToCalendarSystem(const QString &calendarType) const
3139{
3140 if (calendarType == QLatin1String("coptic")) {
3141 return KLocale::CopticCalendar;
3142 } else if (calendarType == QLatin1String("ethiopian")) {
3143 return KLocale::EthiopianCalendar;
3144 } else if (calendarType == QLatin1String("gregorian")) {
3145 return KLocale::QDateCalendar;
3146 } else if (calendarType == QLatin1String("gregorian-proleptic")) {
3147 return KLocale::GregorianCalendar;
3148 } else if (calendarType == QLatin1String("hebrew")) {
3149 return KLocale::HebrewCalendar;
3150 } else if (calendarType == QLatin1String("hijri")) {
3151 return KLocale::IslamicCivilCalendar;
3152 } else if (calendarType == QLatin1String("indian-national")) {
3153 return KLocale::IndianNationalCalendar;
3154 } else if (calendarType == QLatin1String("jalali")) {
3155 return KLocale::JalaliCalendar;
3156 } else if (calendarType == QLatin1String("japanese")) {
3157 return KLocale::JapaneseCalendar;
3158 } else if (calendarType == QLatin1String("julian")) {
3159 return KLocale::JulianCalendar;
3160 } else if (calendarType == QLatin1String("minguo")) {
3161 return KLocale::MinguoCalendar;
3162 } else if (calendarType == QLatin1String("thai")) {
3163 return KLocale::ThaiCalendar;
3164 } else {
3165 return KLocale::QDateCalendar;
3166 }
3167}
3168
3169QString KLocalePrivate::calendarSystemToCalendarType(KLocale::CalendarSystem calendarSystem) const
3170{
3171 switch (calendarSystem) {
3172 case KLocale::QDateCalendar:
3173 return QLatin1String("gregorian");
3174 case KLocale::CopticCalendar:
3175 return QLatin1String("coptic");
3176 case KLocale::EthiopianCalendar:
3177 return QLatin1String("ethiopian");
3178 case KLocale::GregorianCalendar:
3179 return QLatin1String("gregorian-proleptic");
3180 case KLocale::HebrewCalendar:
3181 return QLatin1String("hebrew");
3182 case KLocale::IslamicCivilCalendar:
3183 return QLatin1String("hijri");
3184 case KLocale::IndianNationalCalendar:
3185 return QLatin1String("indian-national");
3186 case KLocale::JalaliCalendar:
3187 return QLatin1String("jalali");
3188 case KLocale::JapaneseCalendar:
3189 return QLatin1String("japanese");
3190 case KLocale::JulianCalendar:
3191 return QLatin1String("julian");
3192 case KLocale::MinguoCalendar:
3193 return QLatin1String("minguo");
3194 case KLocale::ThaiCalendar:
3195 return QLatin1String("thai");
3196 default:
3197 return QLatin1String("gregorian");
3198 }
3199}
3200
3201void KLocalePrivate::setCalendar(const QString &calendarType)
3202{
3203 setCalendarSystem(calendarTypeToCalendarSystem(calendarType));
3204}
3205
3206void KLocalePrivate::setCalendarSystem(KLocale::CalendarSystem calendarSystem)
3207{
3208 m_calendarSystem = calendarSystem;
3209 delete m_calendar;
3210 m_calendar = 0;
3211}
3212
3213QString KLocalePrivate::calendarType() const
3214{
3215 return calendarSystemToCalendarType(m_calendarSystem);
3216}
3217
3218KLocale::CalendarSystem KLocalePrivate::calendarSystem() const
3219{
3220 return m_calendarSystem;
3221}
3222
3223const KCalendarSystem * KLocalePrivate::calendar()
3224{
3225 if (!m_calendar) {
3226 m_calendar = KCalendarSystem::create(m_calendarSystem, m_config, q);
3227 }
3228
3229 return m_calendar;
3230}
3231
3232void KLocalePrivate::setWeekNumberSystem(KLocale::WeekNumberSystem weekNumberSystem)
3233{
3234 m_weekNumberSystem = weekNumberSystem;
3235}
3236
3237KLocale::WeekNumberSystem KLocalePrivate::weekNumberSystem()
3238{
3239 return m_weekNumberSystem;
3240}
3241
3242void KLocalePrivate::copyCatalogsTo(KLocale *locale)
3243{
3244 QMutexLocker lock(kLocaleMutex());
3245 locale->d->m_catalogNames = m_catalogNames;
3246 locale->d->updateCatalogs();
3247}
3248
3249QString KLocalePrivate::localizedFilePath(const QString &filePath) const
3250{
3251 // Stop here if the default language is primary.
3252 if (useDefaultLanguage()) {
3253 return filePath;
3254 }
3255
3256 // Check if l10n sudir is present, stop if not.
3257 QFileInfo fileInfo(filePath);
3258 QString locDirPath = fileInfo.path() + QLatin1String("/l10n");
3259 QFileInfo locDirInfo(locDirPath);
3260 if (!locDirInfo.isDir()) {
3261 return filePath;
3262 }
3263
3264 // Go through possible localized paths by priority of languages,
3265 // return first that exists.
3266 QString fileName = fileInfo.fileName();
3267 foreach(const QString &lang, languageList()) {
3268 // Stop when the default language is reached.
3269 if (lang == KLocale::defaultLanguage()) {
3270 return filePath;
3271 }
3272 QString locFilePath = locDirPath + QLatin1Char('/') + lang + QLatin1Char('/') + fileName;
3273 QFileInfo locFileInfo(locFilePath);
3274 if (locFileInfo.isFile() && locFileInfo.isReadable()) {
3275 return locFilePath;
3276 }
3277 }
3278
3279 return filePath;
3280}
3281
3282QString KLocalePrivate::removeAcceleratorMarker(const QString &label) const
3283{
3284 return ::removeAcceleratorMarker(label);
3285}
3286
3287void KLocalePrivate::setDigitSet(KLocale::DigitSet digitSet)
3288{
3289 m_digitSet = digitSet;
3290}
3291
3292KLocale::DigitSet KLocalePrivate::digitSet() const
3293{
3294 return m_digitSet;
3295}
3296
3297void KLocalePrivate::setMonetaryDigitSet(KLocale::DigitSet digitSet)
3298{
3299 m_monetaryDigitSet = digitSet;
3300}
3301
3302KLocale::DigitSet KLocalePrivate::monetaryDigitSet() const
3303{
3304 return m_monetaryDigitSet;
3305}
3306
3307void KLocalePrivate::setDateTimeDigitSet(KLocale::DigitSet digitSet)
3308{
3309 m_dateTimeDigitSet = digitSet;
3310}
3311
3312KLocale::DigitSet KLocalePrivate::dateTimeDigitSet() const
3313{
3314 return m_dateTimeDigitSet;
3315}
3316
3317Q_GLOBAL_STATIC_WITH_ARGS(QMutex, s_kLocaleMutex, (QMutex::Recursive))
3318
3319QMutex *kLocaleMutex()
3320{
3321 return s_kLocaleMutex();
3322}
KCalendarSystem
KCalendarSystem abstract base class, provides support for local Calendar Systems in KDE.
Definition: kcalendarsystem.h:41
KCalendarSystem::create
static KCalendarSystem * create(const QString &calType=QLatin1String("gregorian"), const KLocale *locale=0)
Definition: kcalendarsystem.cpp:47
KCalendarSystem::readDate
virtual QDate readDate(const QString &str, bool *ok=0) const
Converts a localized date string to a QDate.
Definition: kcalendarsystem.cpp:2333
KCalendarSystem::formatDate
virtual QString formatDate(const QDate &fromDate, KLocale::DateFormat toFormat=KLocale::LongDate) const
Returns a string formatted to the current locale's conventions regarding dates.
Definition: kcalendarsystem.cpp:2048
KCalendarSystem::weekDayName
virtual QString weekDayName(int weekDay, WeekDayNameFormat format=LongDayName) const =0
Gets specific calendar type week day name.
Definition: kcalendarsystem.cpp:1881
KCatalog
This class abstracts a gettext message catalog.
Definition: kcatalog_p.h:36
KCatalog::catalogLocaleDir
static QString catalogLocaleDir(const QString &name, const QString &language)
Finds the locale directory for the given catalog in given language.
Definition: kcatalog.cpp:149
KConfigBase::group
KConfigGroup group(const QByteArray &group)
Returns an object for the named subgroup.
Definition: kconfigbase.cpp:44
KConfigGroup
A class for one specific group in a KConfig object.
Definition: kconfiggroup.h:54
KConfigGroup::readEntry
T readEntry(const QString &key, const T &aDefault) const
Reads the value of an entry specified by pKey in the current group.
Definition: kconfiggroup.h:248
KConfigGroup::hasKey
bool hasKey(const QString &key) const
Checks whether the key has an entry in this group.
Definition: kconfiggroup.cpp:1155
KConfigGroup::writeEntry
void writeEntry(const QString &key, const QVariant &value, WriteConfigFlags pFlags=Normal)
Writes a value to the configuration object.
Definition: kconfiggroup.cpp:1037
KConfigGroup::config
KConfig * config()
Return the config object that this group belongs to.
Definition: kconfiggroup.cpp:610
KConfigGroup::deleteEntry
void deleteEntry(const QString &pKey, WriteConfigFlags pFlags=Normal)
Deletes the entry specified by pKey in the current group.
Definition: kconfiggroup.cpp:1112
KConfig
The central class of the KDE configuration data system.
Definition: kconfig.h:71
KConfig::copyTo
KConfig * copyTo(const QString &file, KConfig *config=0) const
Copies all entries from this config object to a new config object that will save itself to file.
Definition: kconfig.cpp:486
KConfig::sync
void sync()
Definition: kconfig.cpp:388
KConfig::markAsClean
void markAsClean()
Definition: kconfig.cpp:458
KConfig::NoGlobals
@ NoGlobals
Cascade to system settings, but omit user's globals.
Definition: kconfig.h:98
KConfig::groupList
QStringList groupList() const
Definition: kconfig.cpp:261
KConfig::setLocale
bool setLocale(const QString &aLocale)
Sets the locale to aLocale.
Definition: kconfig.cpp:705
KCurrencyCode
Definition: kcurrencycode.h:46
KCurrencyCode::isValid
bool isValid() const
Return if the currency object loaded/initialised correctly.
Definition: kcurrencycode.cpp:266
KCurrencyCode::decimalPlaces
int decimalPlaces() const
Return the number of decimal places required to display the currency subunits.
Definition: kcurrencycode.cpp:256
KCurrencyCode::defaultSymbol
QString defaultSymbol() const
Return the default Symbol for the Currency, e.g.
Definition: kcurrencycode.cpp:218
KCurrencyCode::isoCurrencyCode
QString isoCurrencyCode() const
Return the ISO 4217 Currency Code in Alpha 3 format, e.g.
Definition: kcurrencycode.cpp:167
KDateTime
A class representing a date and time with an associated time zone.
Definition: kdatetime.h:172
KDateTime::isDateOnly
bool isDateOnly() const
Returns whether the instance represents a date/time or a date-only value.
Definition: kdatetime.cpp:832
KDateTime::timeType
SpecType timeType() const
Returns the time specification type of the date/time, i.e.
Definition: kdatetime.cpp:843
KDateTime::date
QDate date() const
Returns the date part of the date/time.
Definition: kdatetime.cpp:838
KDateTime::toString
QString toString(const QString &format) const
Returns the date/time as a string.
Definition: kdatetime.cpp:1434
KDateTime::secsTo
int secsTo(const KDateTime &other) const
Returns the number of seconds from this date/time to the other date/time.
Definition: kdatetime.cpp:1159
KDateTime::dateTime
QDateTime dateTime() const
Returns the date/time component of the instance, ignoring the time zone.
Definition: kdatetime.cpp:840
KDateTime::UTC
@ UTC
a UTC time.
Definition: kdatetime.h:184
KDateTime::OffsetFromUTC
@ OffsetFromUTC
a local time which has a fixed offset from UTC.
Definition: kdatetime.h:185
KDateTime::ClockTime
@ ClockTime
a clock time which ignores time zones and simply uses whatever the local system clock says the time i...
Definition: kdatetime.h:203
KDateTime::TimeZone
@ TimeZone
a time in a specified time zone.
Definition: kdatetime.h:186
KDateTime::timeSpec
Spec timeSpec() const
Returns the time specification of the date/time, i.e.
Definition: kdatetime.cpp:842
KDateTime::currentDateTime
static KDateTime currentDateTime(const Spec &spec)
Returns the current date and time, as reported by the system clock, expressed in a given time specifi...
Definition: kdatetime.cpp:1262
KDayPeriod
Definition: kdayperiod_p.h:55
KDayPeriod::time
QTime time(int hourInPeriod, int minute, int second, int millisecond=0) const
Calculate and return the 24hr time for a given hms in the Day Period.
Definition: kdayperiod.cpp:161
KDayPeriod::isValid
bool isValid() const
Return if the Day Period is valid.
Definition: kdayperiod.cpp:186
KDayPeriod::periodName
QString periodName(KLocale::DateTimeComponentFormat format=KLocale::ShortName) const
Return translated Period Name in the required format e.g.
Definition: kdayperiod.cpp:138
KDayPeriod::hourInPeriod
int hourInPeriod(const QTime &time) const
Calculate and return the hour in the Day Period for a given 24h time.
Definition: kdayperiod.cpp:149
KLocalePrivate
Definition: klocale_p.h:35
KLocalePrivate::formatMoney
virtual QString formatMoney(double num, const QString &currency=QString(), int precision=-1) const
Definition: klocale_kde.cpp:1392
KLocalePrivate::defaultCurrencyCode
static QString defaultCurrencyCode()
Definition: klocale_kde.cpp:3040
KLocalePrivate::dateTimeDigitSet
virtual KLocale::DigitSet dateTimeDigitSet() const
Definition: klocale_kde.cpp:3312
KLocalePrivate::negativePrefixCurrencySymbol
virtual bool negativePrefixCurrencySymbol() const
Definition: klocale_kde.cpp:1279
KLocalePrivate::dateFormat
virtual QString dateFormat() const
Definition: klocale_kde.cpp:2916
KLocalePrivate::binaryUnitDialect
virtual KLocale::BinaryUnitDialect binaryUnitDialect() const
Definition: klocale_kde.cpp:1763
KLocalePrivate::systemCodeset
virtual QByteArray systemCodeset() const
Definition: klocale_kde.cpp:2649
KLocalePrivate::weekDayOfPray
virtual int weekDayOfPray() const
Definition: klocale_kde.cpp:1207
KLocalePrivate::encodeFileNameUTF8
static QByteArray encodeFileNameUTF8(const QString &fileName)
Definition: klocale_kde.cpp:2712
KLocalePrivate::calendarType
virtual QString calendarType() const
Definition: klocale_kde.cpp:3213
KLocalePrivate::decimalSymbol
virtual QString decimalSymbol() const
Definition: klocale_kde.cpp:1217
KLocalePrivate::negativeMonetarySignPosition
virtual KLocale::SignPosition negativeMonetarySignPosition() const
Definition: klocale_kde.cpp:1289
KLocalePrivate::defaultLanguage
static QString defaultLanguage()
Definition: klocale_kde.cpp:3029
KLocalePrivate::setDateFormatShort
virtual void setDateFormatShort(const QString &format)
Definition: klocale_kde.cpp:2873
KLocalePrivate::allCountriesList
virtual QStringList allCountriesList() const
Definition: klocale_kde.cpp:3113
KLocalePrivate::setActiveCatalog
virtual void setActiveCatalog(const QString &catalog)
Sets the active catalog for translation lookup.
Definition: klocale_kde.cpp:878
KLocalePrivate::positiveSign
virtual QString positiveSign() const
Definition: klocale_kde.cpp:1252
KLocalePrivate::monetaryThousandsSeparator
virtual QString monetaryThousandsSeparator() const
Definition: klocale_kde.cpp:1242
KLocalePrivate::prettyFormatDuration
virtual QString prettyFormatDuration(unsigned long mSec) const
Definition: klocale_kde.cpp:1810
KLocalePrivate::currency
virtual KCurrencyCode * currency()
Definition: klocale_kde.cpp:799
KLocalePrivate::splitLocale
static void splitLocale(const QString &locale, QString &language, QString &country, QString &modifier, QString &charset)
Definition: klocale_kde.cpp:742
KLocalePrivate::setEncoding
virtual bool setEncoding(int mibEnum)
Definition: klocale_kde.cpp:3073
KLocalePrivate::setWorkingWeekStartDay
virtual void setWorkingWeekStartDay(int day)
Definition: klocale_kde.cpp:2895
KLocalePrivate::setNegativeMonetarySignPosition
virtual void setNegativeMonetarySignPosition(KLocale::SignPosition signpos)
Definition: klocale_kde.cpp:2967
KLocalePrivate::setCountry
virtual bool setCountry(const QString &country, KConfig *config)
Definition: klocale_kde.cpp:593
KLocalePrivate::formatDate
virtual QString formatDate(const QDate &date, KLocale::DateFormat format=KLocale::LongDate)
Definition: klocale_kde.cpp:1852
KLocalePrivate::setWorkingWeekEndDay
virtual void setWorkingWeekEndDay(int day)
Definition: klocale_kde.cpp:2902
KLocalePrivate::initLanguageList
virtual void initLanguageList(const QString &language, const QString &configLanguages, bool useEnv)
Definition: klocale_kde.cpp:402
KLocalePrivate::currencySymbol
virtual QString currencySymbol() const
Definition: klocale_kde.cpp:1232
KLocalePrivate::setWeekDayOfPray
virtual void setWeekDayOfPray(int day)
Definition: klocale_kde.cpp:2909
KLocalePrivate::formatNumber
virtual QString formatNumber(double num, int precision=-1) const
Definition: klocale_kde.cpp:1456
KLocalePrivate::setCalendar
virtual void setCalendar(const QString &calendarType)
Definition: klocale_kde.cpp:3201
KLocalePrivate::~KLocalePrivate
virtual ~KLocalePrivate()
Destructor.
Definition: klocale_kde.cpp:220
KLocalePrivate::formatLocaleTime
virtual QString formatLocaleTime(const QTime &pTime, KLocale::TimeFormatOptions options=KLocale::TimeDefault) const
Definition: klocale_kde.cpp:2341
KLocalePrivate::setCountryDivisionCode
bool setCountryDivisionCode(const QString &countryDivision)
Definition: klocale_kde.cpp:629
KLocalePrivate::setPositiveMonetarySignPosition
virtual void setPositiveMonetarySignPosition(KLocale::SignPosition signpos)
Definition: klocale_kde.cpp:2962
KLocalePrivate::weekStartDay
virtual int weekStartDay() const
Definition: klocale_kde.cpp:1192
KLocalePrivate::initCountry
virtual void initCountry(const QString &country, const QString &configCountry)
Definition: klocale_kde.cpp:359
KLocalePrivate::setDayPeriods
virtual void setDayPeriods(const QList< KDayPeriod > &dayPeriods)
Definition: klocale_kde.cpp:2449
KLocalePrivate::langLookup
static QString langLookup(const QString &fname, const char *rtype="html")
Definition: klocale_kde.cpp:2589
KLocalePrivate::dayPeriodForTime
virtual KDayPeriod dayPeriodForTime(const QTime &time) const
Definition: klocale_kde.cpp:2482
KLocalePrivate::setTimeFormat
virtual void setTimeFormat(const QString &format)
Definition: klocale_kde.cpp:2883
KLocalePrivate::initDayPeriods
virtual void initDayPeriods(const KConfigGroup &cg)
Definition: klocale_kde.cpp:568
KLocalePrivate::dateFormatShort
virtual QString dateFormatShort() const
Definition: klocale_kde.cpp:2921
KLocalePrivate::initFileNameEncoding
virtual void initFileNameEncoding()
Definition: klocale_kde.cpp:2668
KLocalePrivate::languageList
virtual QStringList languageList() const
Definition: klocale_kde.cpp:2494
KLocalePrivate::use12Clock
virtual bool use12Clock() const
Definition: klocale_kde.cpp:2439
KLocalePrivate::countryCodeToName
virtual QString countryCodeToName(const QString &country) const
Definition: klocale_kde.cpp:3126
KLocalePrivate::timeFormat
virtual QString timeFormat() const
Definition: klocale_kde.cpp:2926
KLocalePrivate::useTranscript
virtual bool useTranscript() const
Definition: klocale_kde.cpp:3045
KLocalePrivate::formatTime
virtual QString formatTime(const QTime &pTime, bool includeSecs=false, bool isDuration=false) const
Definition: klocale_kde.cpp:2329
KLocalePrivate::calendarSystem
KLocale::CalendarSystem calendarSystem() const
Definition: klocale_kde.cpp:3218
KLocalePrivate::q
KLocale * q
Definition: klocale_p.h:1150
KLocalePrivate::setMainCatalog
static void setMainCatalog(const char *catalog)
Definition: klocale_kde.cpp:1857
KLocalePrivate::language
virtual QString language() const
Definition: klocale_kde.cpp:780
KLocalePrivate::encodingMib
virtual int encodingMib() const
Definition: klocale_kde.cpp:3055
KLocalePrivate::digitSetString
static QString digitSetString(KLocale::DigitSet digitSet)
Definition: klocale_kde.cpp:1055
KLocalePrivate::readNumber
virtual double readNumber(const QString &numStr, bool *ok=0) const
Definition: klocale_kde.cpp:1863
KLocalePrivate::getLanguagesFromVariable
static void getLanguagesFromVariable(QStringList &list, const char *variable, bool isLanguageList=false)
Definition: klocale_kde.cpp:329
KLocalePrivate::measureSystem
virtual KLocale::MeasureSystem measureSystem() const
Definition: klocale_kde.cpp:3019
KLocalePrivate::readLocaleTime
virtual QTime readLocaleTime(const QString &str, bool *ok=0, KLocale::TimeFormatOptions options=KLocale::TimeDefault, KLocale::TimeProcessingOptions processing=KLocale::ProcessNonStrict) const
Definition: klocale_kde.cpp:2192
KLocalePrivate::setMonetaryDigitSet
virtual void setMonetaryDigitSet(KLocale::DigitSet digitSet)
Definition: klocale_kde.cpp:3297
KLocalePrivate::initMainCatalogs
virtual void initMainCatalogs()
Definition: klocale_kde.cpp:296
KLocalePrivate::initConfig
virtual void initConfig(KConfig *config)
Definition: klocale_kde.cpp:271
KLocalePrivate::numericDigitGrouping
virtual QList< int > numericDigitGrouping() const
Definition: klocale_kde.cpp:1227
KLocalePrivate::setMeasureSystem
virtual void setMeasureSystem(KLocale::MeasureSystem value)
Definition: klocale_kde.cpp:3024
KLocalePrivate::encoding
virtual const QByteArray encoding()
Definition: klocale_kde.cpp:3050
KLocalePrivate::calendarTypeToCalendarSystem
virtual KLocale::CalendarSystem calendarTypeToCalendarSystem(const QString &calendarType) const
Definition: klocale_kde.cpp:3138
KLocalePrivate::initEncoding
virtual void initEncoding()
Definition: klocale_kde.cpp:2623
KLocalePrivate::decodeFileNameUTF8
static QString decodeFileNameUTF8(const QByteArray &localFileName)
Definition: klocale_kde.cpp:2789
KLocalePrivate::monetaryDigitGrouping
virtual QList< int > monetaryDigitGrouping() const
Definition: klocale_kde.cpp:1247
KLocalePrivate::fileEncodingMib
virtual int fileEncodingMib() const
Definition: klocale_kde.cpp:3060
KLocalePrivate::toArabicDigits
static QString toArabicDigits(const QString &str)
Definition: klocale_kde.cpp:1169
KLocalePrivate::copyCatalogsTo
virtual void copyCatalogsTo(KLocale *locale)
Definition: klocale_kde.cpp:3242
KLocalePrivate::setDigitSet
virtual void setDigitSet(KLocale::DigitSet digitSet)
Definition: klocale_kde.cpp:3287
KLocalePrivate::formatDuration
virtual QString formatDuration(unsigned long mSec) const
Definition: klocale_kde.cpp:1777
KLocalePrivate::config
KConfig * config()
Definition: klocale_kde.cpp:130
KLocalePrivate::init
virtual void init(const QString &catalogName, const QString &language, const QString &country, KSharedConfig::Ptr persistantconfig, KConfig *tempConfig)
Definition: klocale_kde.cpp:229
KLocalePrivate::setMonetaryDecimalPlaces
virtual void setMonetaryDecimalPlaces(int digits)
Definition: klocale_kde.cpp:2982
KLocalePrivate::initCurrency
virtual void initCurrency()
Definition: klocale_kde.cpp:699
KLocalePrivate::KLocalePrivate
KLocalePrivate(KLocale *q_ptr)
Constructors.
Definition: klocale_kde.cpp:106
KLocalePrivate::setThousandsSeparator
virtual void setThousandsSeparator(const QString &separator)
Definition: klocale_kde.cpp:2941
KLocalePrivate::setLanguage
virtual bool setLanguage(const QString &language, KConfig *config)
Definition: klocale_kde.cpp:635
KLocalePrivate::setCurrencySymbol
virtual void setCurrencySymbol(const QString &symbol)
Definition: klocale_kde.cpp:3003
KLocalePrivate::setNumericDigitGrouping
virtual void setNumericDigitGrouping(QList< int > groupList)
Definition: klocale_kde.cpp:2947
KLocalePrivate::updateCatalogs
virtual void updateCatalogs()
Definition: klocale_kde.cpp:827
KLocalePrivate::readTime
virtual QTime readTime(const QString &str, bool *ok=0) const
Definition: klocale_kde.cpp:2108
KLocalePrivate::setMonetaryDigitGrouping
virtual void setMonetaryDigitGrouping(QList< int > groupList)
Definition: klocale_kde.cpp:2993
KLocalePrivate::monetaryDecimalSymbol
virtual QString monetaryDecimalSymbol() const
Definition: klocale_kde.cpp:1237
KLocalePrivate::isApplicationTranslatedInto
virtual bool isApplicationTranslatedInto(const QString &language)
Definition: klocale_kde.cpp:720
KLocalePrivate::systemCountry
virtual QString systemCountry() const
Definition: klocale_kde.cpp:393
KLocalePrivate::calendarSystemToCalendarType
virtual QString calendarSystemToCalendarType(KLocale::CalendarSystem) const
Definition: klocale_kde.cpp:3169
KLocalePrivate::positiveMonetarySignPosition
virtual KLocale::SignPosition positiveMonetarySignPosition() const
Definition: klocale_kde.cpp:1284
KLocalePrivate::monetaryDecimalPlaces
virtual int monetaryDecimalPlaces() const
Definition: klocale_kde.cpp:1269
KLocalePrivate::negativeSign
virtual QString negativeSign() const
Definition: klocale_kde.cpp:1257
KLocalePrivate::setDecimalPlaces
virtual void setDecimalPlaces(int digits)
Definition: klocale_kde.cpp:2931
KLocalePrivate::allDigitSetsList
virtual QList< KLocale::DigitSet > allDigitSetsList() const
Definition: klocale_kde.cpp:1034
KLocalePrivate::DurationType
DurationType
Definition: klocale_p.h:978
KLocalePrivate::HoursDurationType
@ HoursDurationType
Definition: klocale_p.h:980
KLocalePrivate::DaysDurationType
@ DaysDurationType
Definition: klocale_p.h:979
KLocalePrivate::SecondsDurationType
@ SecondsDurationType
Definition: klocale_p.h:982
KLocalePrivate::MinutesDurationType
@ MinutesDurationType
Definition: klocale_p.h:981
KLocalePrivate::readDate
virtual QDate readDate(const QString &str, bool *ok=0)
Definition: klocale_kde.cpp:2093
KLocalePrivate::setPageSize
virtual void setPageSize(int paperFormat)
Definition: klocale_kde.cpp:3013
KLocalePrivate::convertDigits
virtual QString convertDigits(const QString &str, KLocale::DigitSet digitSet, bool ignoreContext=false) const
Definition: klocale_kde.cpp:1145
KLocalePrivate::digitSet
virtual KLocale::DigitSet digitSet() const
Definition: klocale_kde.cpp:3292
KLocalePrivate::readMoney
virtual double readMoney(const QString &numStr, bool *ok=0) const
Definition: klocale_kde.cpp:1950
KLocalePrivate::formatSingleDuration
static QString formatSingleDuration(KLocalePrivate::DurationType durationType, int n)
Definition: klocale_kde.cpp:1795
KLocalePrivate::workingWeekStartDay
virtual int workingWeekStartDay() const
Definition: klocale_kde.cpp:1197
KLocalePrivate::setBinaryUnitDialect
virtual void setBinaryUnitDialect(KLocale::BinaryUnitDialect newDialect)
Definition: klocale_kde.cpp:1768
KLocalePrivate::dayPeriods
virtual QList< KDayPeriod > dayPeriods() const
Definition: klocale_kde.cpp:2461
KLocalePrivate::localizedFilePath
virtual QString localizedFilePath(const QString &filePath) const
Definition: klocale_kde.cpp:3249
KLocalePrivate::formatDateTime
static QString formatDateTime(const KLocale *locale, const QDateTime &dateTime, KLocale::DateFormat, bool includeSeconds, int daysToNow, int secsToNow)
Definition: klocale_kde.cpp:2504
KLocalePrivate::weekNumberSystem
KLocale::WeekNumberSystem weekNumberSystem()
Definition: klocale_kde.cpp:3237
KLocalePrivate::installedLanguages
virtual QStringList installedLanguages()
Definition: klocale_kde.cpp:3091
KLocalePrivate::currencyCodeList
virtual QStringList currencyCodeList() const
Definition: klocale_kde.cpp:2499
KLocalePrivate::setDateTimeDigitSet
virtual void setDateTimeDigitSet(KLocale::DigitSet digitSet)
Definition: klocale_kde.cpp:3307
KLocalePrivate::defaultCountry
static QString defaultCountry()
Definition: klocale_kde.cpp:3035
KLocalePrivate::operator=
KLocalePrivate & operator=(const KLocalePrivate &rhs)
Assignment operator.
Definition: klocale_kde.cpp:124
KLocalePrivate::setPositiveSign
virtual void setPositiveSign(const QString &sign)
Definition: klocale_kde.cpp:2952
KLocalePrivate::currencyCode
virtual QString currencyCode() const
Definition: klocale_kde.cpp:807
KLocalePrivate::allLanguagesList
virtual QStringList allLanguagesList()
Definition: klocale_kde.cpp:3083
KLocalePrivate::insertCatalog
virtual void insertCatalog(const QString &catalog)
Definition: klocale_kde.cpp:812
KLocalePrivate::translateQt
virtual QString translateQt(const char *context, const char *sourceText, const char *comment) const
Definition: klocale_kde.cpp:973
KLocalePrivate::nounDeclension
virtual bool nounDeclension() const
Definition: klocale_kde.cpp:1182
KLocalePrivate::setWeekStartDay
virtual void setWeekStartDay(int day)
Definition: klocale_kde.cpp:2888
KLocalePrivate::workingWeekEndDay
virtual int workingWeekEndDay() const
Definition: klocale_kde.cpp:1202
KLocalePrivate::setWeekNumberSystem
void setWeekNumberSystem(KLocale::WeekNumberSystem weekNumberSystem)
Definition: klocale_kde.cpp:3232
KLocalePrivate::setDateFormat
virtual void setDateFormat(const QString &format)
Definition: klocale_kde.cpp:2868
KLocalePrivate::digitSetToName
virtual QString digitSetToName(KLocale::DigitSet digitSet, bool withDigits=false) const
Definition: klocale_kde.cpp:1089
KLocalePrivate::calendar
virtual const KCalendarSystem * calendar()
Definition: klocale_kde.cpp:3223
KLocalePrivate::setMonetaryThousandsSeparator
virtual void setMonetaryThousandsSeparator(const QString &separator)
Definition: klocale_kde.cpp:2987
KLocalePrivate::formatByteSize
virtual QString formatByteSize(double size)
Definition: klocale_kde.cpp:1758
KLocalePrivate::codecForEncoding
virtual QTextCodec * codecForEncoding() const
Definition: klocale_kde.cpp:3068
KLocalePrivate::translateRawFrom
virtual void translateRawFrom(const char *catname, const char *msgctxt, const char *msgid, const char *msgid_plural=0, unsigned long n=0, QString *language=0, QString *translation=0) const
Definition: klocale_kde.cpp:890
KLocalePrivate::positivePrefixCurrencySymbol
virtual bool positivePrefixCurrencySymbol() const
Definition: klocale_kde.cpp:1274
KLocalePrivate::setNegativePrefixCurrencySymbol
virtual void setNegativePrefixCurrencySymbol(bool prefix)
Definition: klocale_kde.cpp:2977
KLocalePrivate::systemLanguageList
virtual QStringList systemLanguageList() const
Definition: klocale_kde.cpp:447
KLocalePrivate::setPositivePrefixCurrencySymbol
virtual void setPositivePrefixCurrencySymbol(bool prefix)
Definition: klocale_kde.cpp:2972
KLocalePrivate::setDecimalSymbol
virtual void setDecimalSymbol(const QString &symbol)
Definition: klocale_kde.cpp:2936
KLocalePrivate::setMonetaryDecimalSymbol
virtual void setMonetaryDecimalSymbol(const QString &symbol)
Definition: klocale_kde.cpp:2998
KLocalePrivate::removeCatalog
virtual void removeCatalog(const QString &catalog)
Definition: klocale_kde.cpp:861
KLocalePrivate::dateMonthNamePossessive
virtual bool dateMonthNamePossessive() const
Definition: klocale_kde.cpp:1187
KLocalePrivate::initFormat
virtual void initFormat()
Reads the format configuration from disk.
Definition: klocale_kde.cpp:452
KLocalePrivate::countryDivisionCode
QString countryDivisionCode() const
Definition: klocale_kde.cpp:790
KLocalePrivate::pageSize
virtual int pageSize() const
Definition: klocale_kde.cpp:3008
KLocalePrivate::thousandsSeparator
virtual QString thousandsSeparator() const
Definition: klocale_kde.cpp:1222
KLocalePrivate::dialectUnitsList
QList< QString > dialectUnitsList(KLocale::BinaryUnitDialect dialect)
Definition: klocale_kde.cpp:1620
KLocalePrivate::removeAcceleratorMarker
virtual QString removeAcceleratorMarker(const QString &label) const
Definition: klocale_kde.cpp:3282
KLocalePrivate::monetaryDigitSet
virtual KLocale::DigitSet monetaryDigitSet() const
Definition: klocale_kde.cpp:3302
KLocalePrivate::formatLong
virtual QString formatLong(long num) const
Definition: klocale_kde.cpp:1465
KLocalePrivate::languageCodeToName
virtual QString languageCodeToName(const QString &language)
Definition: klocale_kde.cpp:3103
KLocalePrivate::setNegativeSign
virtual void setNegativeSign(const QString &sign)
Definition: klocale_kde.cpp:2957
KLocalePrivate::setDateMonthNamePossessive
virtual void setDateMonthNamePossessive(bool possessive)
Definition: klocale_kde.cpp:2878
KLocalePrivate::useDefaultLanguage
virtual bool useDefaultLanguage() const
Definition: klocale_kde.cpp:2618
KLocalePrivate::country
virtual QString country() const
Definition: klocale_kde.cpp:785
KLocalePrivate::copy
virtual void copy(const KLocalePrivate &rhs)
Definition: klocale_kde.cpp:139
KLocalePrivate::decimalPlaces
virtual int decimalPlaces() const
Definition: klocale_kde.cpp:1212
KLocalePrivate::setCurrencyCode
virtual void setCurrencyCode(const QString &newCurrencyCode)
Definition: klocale_kde.cpp:711
KLocalePrivate::setCalendarSystem
virtual void setCalendarSystem(KLocale::CalendarSystem)
Definition: klocale_kde.cpp:3206
KLocale
KLocale provides support for country specific stuff like the national language.
Definition: klocale.h:70
KLocale::WeekNumberSystem
WeekNumberSystem
Definition: klocale.h:815
KLocale::IsoWeekNumber
@ IsoWeekNumber
ISO Week Number.
Definition: klocale.h:817
KLocale::DigitSet
DigitSet
Definition: klocale.h:309
KLocale::KannadaDigits
@ KannadaDigits
೦೧೨೩೪೫೬೭೮೯ (Kannada)
Definition: klocale.h:318
KLocale::ArabicIndicDigits
@ ArabicIndicDigits
٠١٢٣٤٥٦٧٨٩ (eastern Arabic dialects)
Definition: klocale.h:312
KLocale::EasternArabicIndicDigits
@ EasternArabicIndicDigits
۰۱۲۳۴۵۶۷۸۹ (Persian and Urdu)
Definition: klocale.h:313
KLocale::OriyaDigits
@ OriyaDigits
୦୧୨୩୪୫୬୭୮୯ (Oriya)
Definition: klocale.h:321
KLocale::ThaiDigits
@ ThaiDigits
๐๑๒๓๔๕๖๗๘๙ (Thai)
Definition: klocale.h:324
KLocale::ArabicDigits
@ ArabicDigits
0123456789 (European and some Asian languages and western Arabic dialects)
Definition: klocale.h:310
KLocale::TeluguDigits
@ TeluguDigits
౦౧౨౩౪౫౬౭౯ (Telugu)
Definition: klocale.h:323
KLocale::TamilDigits
@ TamilDigits
௦௧௨௩௪௫௬௭௮ (Tamil)
Definition: klocale.h:322
KLocale::GurmukhiDigits
@ GurmukhiDigits
੦੧੨੩੪੫੬੭੮੯ (Punjabi)
Definition: klocale.h:317
KLocale::BengaliDigits
@ BengaliDigits
০১২৩৪৫৬৭৮৯ (Bengali and Assamese)
Definition: klocale.h:315
KLocale::GujaratiDigits
@ GujaratiDigits
૦૧૨૩૪૫૬૭૮૯ (Gujarati)
Definition: klocale.h:316
KLocale::MalayalamDigits
@ MalayalamDigits
൦൧൨൩൪൫൬൭൮൯ (Malayalam)
Definition: klocale.h:320
KLocale::KhmerDigits
@ KhmerDigits
០១២៣៤៥៦៧៨៩ (Khmer)
Definition: klocale.h:319
KLocale::DevenagariDigits
@ DevenagariDigits
०१२३४५६७८९ (Hindi)
Definition: klocale.h:314
KLocale::formatDate
QString formatDate(const QDate &date, DateFormat format=LongDate) const
Returns a string formatted to the current locale's conventions regarding dates.
Definition: klocale.cpp:368
KLocale::BinarySizeUnits
BinarySizeUnits
These binary units are used in KDE by the formatByteSize() functions.
Definition: klocale.h:621
KLocale::UnitLastUnit
@ UnitLastUnit
Definition: klocale.h:635
KLocale::UnitYottaByte
@ UnitYottaByte
YiB/YB/YB 2^80/10^24 bytes.
Definition: klocale.h:634
KLocale::DefaultBinaryUnits
@ DefaultBinaryUnits
Auto-choose a unit such that the result is in the range [0, 1000 or 1024)
Definition: klocale.h:623
KLocale::SignPosition
SignPosition
Various positions for where to place the positive or negative sign when they are related to a monetar...
Definition: klocale.h:281
KLocale::AfterMoney
@ AfterMoney
Suffix the currency symbol with the sign, e.g.
Definition: klocale.h:301
KLocale::ParensAround
@ ParensAround
Put parantheses around the quantity, e.g.
Definition: klocale.h:285
KLocale::BeforeMoney
@ BeforeMoney
Prefix the currency symbol with the sign, e.g.
Definition: klocale.h:297
KLocale::BeforeQuantityMoney
@ BeforeQuantityMoney
Prefix the quantity with the sign, e.g.
Definition: klocale.h:289
KLocale::AfterQuantityMoney
@ AfterQuantityMoney
Suffix the quanitity with the sign, e.g.
Definition: klocale.h:293
KLocale::TimeFormatOption
TimeFormatOption
Definition: klocale.h:1017
KLocale::TimeWithoutSeconds
@ TimeWithoutSeconds
Exclude the seconds part of the time from display.
Definition: klocale.h:1020
KLocale::TimeDuration
@ TimeDuration
Read/format time string as duration.
Definition: klocale.h:1025
KLocale::TimeFoldHours
@ TimeFoldHours
Read/format time string as duration.
Definition: klocale.h:1030
KLocale::TimeWithoutAmPm
@ TimeWithoutAmPm
Read/format time string without am/pm suffix but keep the 12/24h format as specified by locale time f...
Definition: klocale.h:1021
KLocale::TimeDefault
@ TimeDefault
Default formatting using seconds and the format as specified by the locale.
Definition: klocale.h:1018
KLocale::BinaryUnitDialect
BinaryUnitDialect
This enum chooses what dialect is used for binary units.
Definition: klocale.h:656
KLocale::MetricBinaryDialect
@ MetricBinaryDialect
SI Units, kB, MB, etc. 10^(3*n)
Definition: klocale.h:660
KLocale::LastBinaryDialect
@ LastBinaryDialect
Definition: klocale.h:661
KLocale::IECBinaryDialect
@ IECBinaryDialect
KDE Default, KiB, MiB, etc. 2^(10*n)
Definition: klocale.h:658
KLocale::DefaultBinaryDialect
@ DefaultBinaryDialect
Used if no specific preference.
Definition: klocale.h:657
KLocale::JEDECBinaryDialect
@ JEDECBinaryDialect
KDE 3.5 default, KB, MB, etc. 2^(10*n)
Definition: klocale.h:659
KLocale::ReadDateFlags
ReadDateFlags
Flags for readDate()
Definition: klocale.h:1249
KLocale::splitLocale
static void splitLocale(const QString &locale, QString &language, QString &country, QString &modifier, QString &charset)
Parses locale string into distinct parts.
Definition: klocale.cpp:105
KLocale::defaultCurrencyCode
static QString defaultCurrencyCode()
Definition: klocale.cpp:625
KLocale::ProcessStrict
@ ProcessStrict
Process time in a strict manner, ie.
Definition: klocale.h:1326
KLocale::formatLocaleTime
QString formatLocaleTime(const QTime &pTime, TimeFormatOptions options=KLocale::TimeDefault) const
Definition: klocale.cpp:424
KLocale::MeasureSystem
MeasureSystem
The Metric system will give you information in mm, while the Imperial system will give you informatio...
Definition: klocale.h:1780
KLocale::Metric
@ Metric
Metric system (used e.g. in Europe)
Definition: klocale.h:1781
KLocale::DateFormat
DateFormat
Format for date string.
Definition: klocale.h:922
KLocale::FancyShortDate
@ FancyShortDate
Same as ShortDate for dates a week or more ago.
Definition: klocale.h:925
KLocale::ShortDate
@ ShortDate
Locale Short date format, e.g.
Definition: klocale.h:923
KLocale::FancyLongDate
@ FancyLongDate
Same as LongDate for dates a week or more ago.
Definition: klocale.h:928
KLocale::LongDate
@ LongDate
Locale Long date format, e.g.
Definition: klocale.h:924
KLocale::Seconds
@ Seconds
Include the seconds value.
Definition: klocale.h:969
KLocale::TimeZone
@ TimeZone
Include a time zone string.
Definition: klocale.h:968
KLocale::defaultLanguage
static QString defaultLanguage()
Returns the name of the internal language.
Definition: klocale.cpp:615
KLocale::calendar
const KCalendarSystem * calendar() const
Returns a pointer to the calendar system object.
Definition: klocale.cpp:705
KLocale::CalendarSystem
CalendarSystem
Definition: klocale.h:780
KLocale::IslamicCivilCalendar
@ IslamicCivilCalendar
Islamic Civil Calendar, aka Hijri, not the Lunar Calendar.
Definition: klocale.h:792
KLocale::IndianNationalCalendar
@ IndianNationalCalendar
Indian National Calendar, not the Lunar Calendar.
Definition: klocale.h:794
KLocale::JapaneseCalendar
@ JapaneseCalendar
Japanese Calendar, Gregorian calculation using Japanese Era (Nengô)
Definition: klocale.h:799
KLocale::QDateCalendar
@ QDateCalendar
KDE Default, hybrid of Gregorian and Julian as used by QDate.
Definition: klocale.h:781
KLocale::HebrewCalendar
@ HebrewCalendar
Hebrew Calendar, aka Jewish Calendar.
Definition: klocale.h:789
KLocale::EthiopianCalendar
@ EthiopianCalendar
Ethiopian Calendar, aka Ethiopic Calendar.
Definition: klocale.h:786
KLocale::CopticCalendar
@ CopticCalendar
Coptic Calendar as used Coptic Church and some parts of Egypt.
Definition: klocale.h:785
KLocale::GregorianCalendar
@ GregorianCalendar
Gregorian Calendar, pure proleptic implementation.
Definition: klocale.h:788
KLocale::ThaiCalendar
@ ThaiCalendar
Thai Calendar, aka Buddhist or Thai Buddhist.
Definition: klocale.h:803
KLocale::JalaliCalendar
@ JalaliCalendar
Jalali Calendar, aka Persian or Iranian, also used in Afghanistan.
Definition: klocale.h:796
KLocale::MinguoCalendar
@ MinguoCalendar
Minguo Calendar, aka ROC, Republic of China or Taiwanese.
Definition: klocale.h:802
KLocale::JulianCalendar
@ JulianCalendar
Julian Calendar, as used in Orthodox Churches.
Definition: klocale.h:801
KLocale::ReadTimeFlags
ReadTimeFlags
Flags for the old version of readTime()
Definition: klocale.h:1297
KLocale::WithSeconds
@ WithSeconds
Only accept a time string with seconds. Default (no flag set)
Definition: klocale.h:1298
KLocale::languageList
QStringList languageList() const
Returns the language codes selected by user, ordered by decreasing priority.
Definition: klocale.cpp:439
KLocale::ShortName
@ ShortName
Short text format, e.g.
Definition: klocale.h:914
KLocalizedString::notifyCatalogsUpdated
static void notifyCatalogsUpdated(const QStringList &languages, const QList< KCatalogName > &catalogs)
Definition: klocalizedstring.cpp:974
KSharedConfig
KConfig variant using shared memory.
Definition: ksharedconfig.h:41
KSharedConfig::openConfig
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, const char *resourceType="config")
Creates a KSharedConfig object to manipulate a configuration file.
Definition: ksharedconfig.cpp:31
KSharedConfig::Ptr
KSharedPtr< KSharedConfig > Ptr
Definition: ksharedconfig.h:43
KSharedPtr< KSharedConfig >
KSharedPtr::data
T * data()
Definition: ksharedptr.h:111
KStandardDirs::findAllResources
QStringList findAllResources(const char *type, const QString &filter=QString(), SearchOptions options=NoSearchOptions) const
Tries to find all resources with the specified type.
Definition: kstandarddirs.cpp:900
KStandardDirs::locate
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
This function is just for convenience.
Definition: kstandarddirs.cpp:2091
KStandardDirs::resourceDirs
QStringList resourceDirs(const char *type) const
This function is used internally by almost all other function as it serves and fills the directories ...
Definition: kstandarddirs.cpp:1069
QDateTime
QHash
Definition: ksycocafactory.h:28
QList
Definition: kaboutdata.h:33
QStringList
QString
common_helpers_p.h
K_GLOBAL_STATIC
#define K_GLOBAL_STATIC(TYPE, NAME)
This macro makes it easy to use non-POD types as global statics.
Definition: kglobal.h:221
kDebug
#define kDebug
Definition: kdebug.h:316
kWarning
#define kWarning
Definition: kdebug.h:322
kcalendarsystem.h
kcatalog_p.h
kcatalogname_p.h
kcomponentdata.h
kconfig.h
kconfiggroup.h
kcurrencycode.h
kdatetime.h
Date/times with associated time zone.
kdayperiod_p.h
kdebug.h
kglobal.h
stripStringAndPreceedingSeparator
static void stripStringAndPreceedingSeparator(QString &inout, const QLatin1String &strip2char)
Definition: klocale_kde.cpp:2126
_inc_by_one
static void _inc_by_one(QString &str, int position)
Definition: klocale_kde.cpp:1471
isUnicodeNonCharacter
static bool isUnicodeNonCharacter(uint ucs4)
Definition: klocale_kde.cpp:2707
put_it_in
static void put_it_in(QChar *buffer, int &index, const QString &s)
Definition: klocale_kde.cpp:1294
stripStringAndSucceedingSeparator
static void stripStringAndSucceedingSeparator(QString &inout, const QLatin1String &strip2char)
Definition: klocale_kde.cpp:2153
read3ConfigBoolEntry
#define read3ConfigBoolEntry(key, default, save)
readConfigEntry
#define readConfigEntry(key, default, save)
kLocaleMutex
QMutex * kLocaleMutex()
Definition: klocale_kde.cpp:3319
stripAmPmFormat
static void stripAmPmFormat(QString &inout)
Definition: klocale_kde.cpp:2169
readConfigNumEntry
#define readConfigNumEntry(key, default, save, type)
CACHE_BYTE_FMT
#define CACHE_BYTE_FMT(ctxt_text)
readInt
static int readInt(const QString &str, int &pos)
helper function to read integers
Definition: klocale_kde.cpp:2079
_round
static void _round(QString &str, int precision)
Definition: klocale_kde.cpp:1515
klocale_p.h
kLocaleMutex
QMutex * kLocaleMutex()
Definition: klocale_kde.cpp:3319
klocalizedstring.h
i18n
QString i18n(const char *text)
Returns a localized version of a string.
Definition: klocalizedstring.h:630
I18N_NOOP2_NOSTRIP
#define I18N_NOOP2_NOSTRIP(ctxt, text)
Definition: klocalizedstring.h:102
i18nc
QString i18nc(const char *ctxt, const char *text)
Returns a localized version of a string and a context.
Definition: klocalizedstring.h:797
i18ncp
QString i18ncp(const char *ctxt, const char *sing, const char *plur, const A1 &a1)
Returns a localized version of a string with 1 argument and a context using correct plural form.
Definition: klocalizedstring.h:1123
kstandarddirs.h
prefix
QString prefix()
Definition: kstandarddirs_win.cpp:28
Q_GLOBAL_STATIC_WITH_ARGS
Q_GLOBAL_STATIC_WITH_ARGS(org::kde::KLauncher, klauncherIface,(QString::fromLatin1("org.kde.klauncher"), QString::fromLatin1("/KLauncher"), QDBusConnection::sessionBus())) org
Definition: ktoolinvocation.cpp:55
KGlobal::hasMainComponent
bool hasMainComponent()
Definition: kglobal.cpp:151
KGlobal::dirs
KStandardDirs * dirs()
Returns the application standard dirs object.
KGlobal::locale
KLocale * locale()
Returns the global locale object.
Definition: kglobal.cpp:170
KGlobal::config
KSharedConfigPtr config()
Returns the general config object.
Definition: kglobal.cpp:139
KCatalogName
Definition: kcatalogname_p.h:26
KCatalogName::name
QString name
Definition: kcatalogname_p.h:28
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal