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

KDECore

  • sources
  • kde-4.12
  • kdelibs
  • 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 
67 class KLocaleStaticData
68 {
69 public:
70 
71  KLocaleStaticData();
72 
73  QString maincatalog;
74 
75  // FIXME: Temporary until full language-sensitivity implemented.
76  QHash<KLocale::DigitSet, QStringList> languagesUsingDigitSet;
77 };
78 
79 KLocaleStaticData::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 
98 K_GLOBAL_STATIC(KLocaleStaticData, staticData)
99 
100 
101 QDebug operator<<(QDebug debug, const KCatalogName &cn)
102 {
103  return debug << cn.name << cn.loadCount;
104 }
105 
106 KLocalePrivate::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 
119 KLocalePrivate::KLocalePrivate(const KLocalePrivate &rhs)
120 {
121  copy(rhs);
122 }
123 
124 KLocalePrivate &KLocalePrivate::operator=(const KLocalePrivate &rhs)
125 {
126  copy(rhs);
127  return *this;
128 }
129 
130 KConfig *KLocalePrivate::config()
131 {
132  if (m_config != KSharedConfig::Ptr()) {
133  return m_config.data();
134  } else {
135  return KGlobal::config().data();
136  }
137 }
138 
139 void 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 
220 KLocalePrivate::~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
229 void 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
271 void 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 
296 void 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 
329 void 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
359 void 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 
393 QString 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 
402 void 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 
447 QStringList KLocalePrivate::systemLanguageList() const
448 {
449  return QStringList();
450 }
451 
452 void 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 
568 void 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 
593 bool 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 
629 bool KLocalePrivate::setCountryDivisionCode(const QString &countryDivisionCode)
630 {
631  m_countryDivisionCode = countryDivisionCode;
632  return true;
633 }
634 
635 bool 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.
661 bool 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 
699 void 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 
711 void 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 
720 bool 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 
742 void 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 
780 QString KLocalePrivate::language() const
781 {
782  return m_language;
783 }
784 
785 QString KLocalePrivate::country() const
786 {
787  return m_country;
788 }
789 
790 QString KLocalePrivate::countryDivisionCode() const
791 {
792  if (m_countryDivisionCode.isEmpty()) {
793  return country().toUpper();
794  } else {
795  return m_countryDivisionCode;
796  }
797 }
798 
799 KCurrencyCode *KLocalePrivate::currency()
800 {
801  if (!m_currency) {
802  initCurrency();
803  }
804  return m_currency;
805 }
806 
807 QString KLocalePrivate::currencyCode() const
808 {
809  return m_currencyCode;
810 }
811 
812 void 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 
827 void 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 
861 void 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 
878 void 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 
890 void 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 
973 QString 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 
1034 QList<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 
1055 QString 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 
1089 QString 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 
1145 QString 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 
1169 QString 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 
1182 bool KLocalePrivate::nounDeclension() const
1183 {
1184  return m_nounDeclension;
1185 }
1186 
1187 bool KLocalePrivate::dateMonthNamePossessive() const
1188 {
1189  return m_dateMonthNamePossessive;
1190 }
1191 
1192 int KLocalePrivate::weekStartDay() const
1193 {
1194  return m_weekStartDay;
1195 }
1196 
1197 int KLocalePrivate::workingWeekStartDay() const
1198 {
1199  return m_workingWeekStartDay;
1200 }
1201 
1202 int KLocalePrivate::workingWeekEndDay() const
1203 {
1204  return m_workingWeekEndDay;
1205 }
1206 
1207 int KLocalePrivate::weekDayOfPray() const
1208 {
1209  return m_weekDayOfPray;
1210 }
1211 
1212 int KLocalePrivate::decimalPlaces() const
1213 {
1214  return m_decimalPlaces;
1215 }
1216 
1217 QString KLocalePrivate::decimalSymbol() const
1218 {
1219  return m_decimalSymbol;
1220 }
1221 
1222 QString KLocalePrivate::thousandsSeparator() const
1223 {
1224  return m_thousandsSeparator;
1225 }
1226 
1227 QList<int> KLocalePrivate::numericDigitGrouping() const
1228 {
1229  return m_numericDigitGrouping;
1230 }
1231 
1232 QString KLocalePrivate::currencySymbol() const
1233 {
1234  return m_currencySymbol;
1235 }
1236 
1237 QString KLocalePrivate::monetaryDecimalSymbol() const
1238 {
1239  return m_monetaryDecimalSymbol;
1240 }
1241 
1242 QString KLocalePrivate::monetaryThousandsSeparator() const
1243 {
1244  return m_monetaryThousandsSeparator;
1245 }
1246 
1247 QList<int> KLocalePrivate::monetaryDigitGrouping() const
1248 {
1249  return m_monetaryDigitGrouping;
1250 }
1251 
1252 QString KLocalePrivate::positiveSign() const
1253 {
1254  return m_positiveSign;
1255 }
1256 
1257 QString KLocalePrivate::negativeSign() const
1258 {
1259  return m_negativeSign;
1260 }
1261 
1262 /* Just copy to keep the diff looking clean, delete later
1263 int KLocale::fracDigits() const
1264 {
1265  return monetaryDecimalPlaces();
1266 }
1267 */
1268 
1269 int KLocalePrivate::monetaryDecimalPlaces() const
1270 {
1271  return m_monetaryDecimalPlaces;
1272 }
1273 
1274 bool KLocalePrivate::positivePrefixCurrencySymbol() const
1275 {
1276  return m_positivePrefixCurrencySymbol;
1277 }
1278 
1279 bool KLocalePrivate::negativePrefixCurrencySymbol() const
1280 {
1281  return m_negativePrefixCurrencySymbol;
1282 }
1283 
1284 KLocale::SignPosition KLocalePrivate::positiveMonetarySignPosition() const
1285 {
1286  return m_positiveMonetarySignPosition;
1287 }
1288 
1289 KLocale::SignPosition KLocalePrivate::negativeMonetarySignPosition() const
1290 {
1291  return m_negativeMonetarySignPosition;
1292 }
1293 
1294 static 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 
1301 static 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)
1308 QList<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.
1319 QString 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
1348 QString 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 
1392 QString 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 
1456 QString 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 
1465 QString KLocalePrivate::formatLong(long num) const
1466 {
1467  return formatNumber((double)num, 0);
1468 }
1469 
1470 // increase the digit at 'position' by one
1471 static 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'
1515 static 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 
1563 QString 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
1620 QList<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 
1700 QString 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 
1758 QString KLocalePrivate::formatByteSize(double size)
1759 {
1760  return formatByteSize(size, 1);
1761 }
1762 
1763 KLocale::BinaryUnitDialect KLocalePrivate::binaryUnitDialect() const
1764 {
1765  return m_binaryUnitDialect;
1766 }
1767 
1768 void 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 
1777 QString 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 
1795 QString 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 
1810 QString 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 
1852 QString KLocalePrivate::formatDate(const QDate &date, KLocale::DateFormat format)
1853 {
1854  return calendar()->formatDate(date, format);
1855 }
1856 
1857 void KLocalePrivate::setMainCatalog(const char *catalog)
1858 {
1859  KLocaleStaticData *s = staticData;
1860  s->maincatalog = QString::fromUtf8(catalog);
1861 }
1862 
1863 double 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 
1950 double 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 
2079 static 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 
2093 QDate KLocalePrivate::readDate(const QString &intstr, bool *ok)
2094 {
2095  return calendar()->readDate(intstr, ok);
2096 }
2097 
2098 QDate KLocalePrivate::readDate(const QString &intstr, KLocale::ReadDateFlags flags, bool *ok)
2099 {
2100  return calendar()->readDate(intstr, flags, ok);
2101 }
2102 
2103 QDate KLocalePrivate::readDate(const QString &intstr, const QString &fmt, bool *ok)
2104 {
2105  return calendar()->readDate(intstr, fmt, ok);
2106 }
2107 
2108 QTime 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 
2117 QTime 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.
2126 static 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.
2153 static 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.
2169 static 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 
2192 QTime 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 
2329 QString 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 
2341 QString 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 
2439 bool 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 
2449 void 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 
2461 QList<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 
2482 KDayPeriod 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 
2494 QStringList KLocalePrivate::languageList() const
2495 {
2496  return m_languageList;
2497 }
2498 
2499 QStringList KLocalePrivate::currencyCodeList() const
2500 {
2501  return m_currencyCodeList;
2502 }
2503 
2504 QString 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 
2547 QString 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 
2555 QString 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 
2589 QString 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 
2618 bool KLocalePrivate::useDefaultLanguage() const
2619 {
2620  return language() == KLocale::defaultLanguage();
2621 }
2622 
2623 void 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 
2649 QByteArray 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 
2668 void 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 
2707 static inline bool isUnicodeNonCharacter(uint ucs4)
2708 {
2709  return (ucs4 & 0xfffe) == 0xfffe || (ucs4 - 0xfdd0U) < 16;
2710 }
2711 
2712 QByteArray 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 
2789 QString 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 
2851 error:
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 
2868 void KLocalePrivate::setDateFormat(const QString &format)
2869 {
2870  m_dateFormat = format.trimmed();
2871 }
2872 
2873 void KLocalePrivate::setDateFormatShort(const QString &format)
2874 {
2875  m_dateFormatShort = format.trimmed();
2876 }
2877 
2878 void KLocalePrivate::setDateMonthNamePossessive(bool possessive)
2879 {
2880  m_dateMonthNamePossessive = possessive;
2881 }
2882 
2883 void KLocalePrivate::setTimeFormat(const QString &format)
2884 {
2885  m_timeFormat = format.trimmed();
2886 }
2887 
2888 void KLocalePrivate::setWeekStartDay(int day)
2889 {
2890  if (day >= 1 && day <= calendar()->daysInWeek(QDate())) {
2891  m_weekStartDay = day;
2892  }
2893 }
2894 
2895 void KLocalePrivate::setWorkingWeekStartDay(int day)
2896 {
2897  if (day >= 1 && day <= calendar()->daysInWeek(QDate())) {
2898  m_workingWeekStartDay = day;
2899  }
2900 }
2901 
2902 void KLocalePrivate::setWorkingWeekEndDay(int day)
2903 {
2904  if (day >= 1 && day <= calendar()->daysInWeek(QDate())) {
2905  m_workingWeekEndDay = day;
2906  }
2907 }
2908 
2909 void KLocalePrivate::setWeekDayOfPray(int day)
2910 {
2911  if (day >= 0 && day <= calendar()->daysInWeek(QDate())) { // 0 = None
2912  m_weekDayOfPray = day;
2913  }
2914 }
2915 
2916 QString KLocalePrivate::dateFormat() const
2917 {
2918  return m_dateFormat;
2919 }
2920 
2921 QString KLocalePrivate::dateFormatShort() const
2922 {
2923  return m_dateFormatShort;
2924 }
2925 
2926 QString KLocalePrivate::timeFormat() const
2927 {
2928  return m_timeFormat;
2929 }
2930 
2931 void KLocalePrivate::setDecimalPlaces(int digits)
2932 {
2933  m_decimalPlaces = digits;
2934 }
2935 
2936 void KLocalePrivate::setDecimalSymbol(const QString &symbol)
2937 {
2938  m_decimalSymbol = symbol.trimmed();
2939 }
2940 
2941 void KLocalePrivate::setThousandsSeparator(const QString &separator)
2942 {
2943  // allow spaces here
2944  m_thousandsSeparator = separator;
2945 }
2946 
2947 void KLocalePrivate::setNumericDigitGrouping(QList<int> groupList)
2948 {
2949  m_numericDigitGrouping = groupList;
2950 }
2951 
2952 void KLocalePrivate::setPositiveSign(const QString &sign)
2953 {
2954  m_positiveSign = sign.trimmed();
2955 }
2956 
2957 void KLocalePrivate::setNegativeSign(const QString &sign)
2958 {
2959  m_negativeSign = sign.trimmed();
2960 }
2961 
2962 void KLocalePrivate::setPositiveMonetarySignPosition(KLocale::SignPosition signpos)
2963 {
2964  m_positiveMonetarySignPosition = signpos;
2965 }
2966 
2967 void KLocalePrivate::setNegativeMonetarySignPosition(KLocale::SignPosition signpos)
2968 {
2969  m_negativeMonetarySignPosition = signpos;
2970 }
2971 
2972 void KLocalePrivate::setPositivePrefixCurrencySymbol(bool prefix)
2973 {
2974  m_positivePrefixCurrencySymbol = prefix;
2975 }
2976 
2977 void KLocalePrivate::setNegativePrefixCurrencySymbol(bool prefix)
2978 {
2979  m_negativePrefixCurrencySymbol = prefix;
2980 }
2981 
2982 void KLocalePrivate::setMonetaryDecimalPlaces(int digits)
2983 {
2984  m_monetaryDecimalPlaces = digits;
2985 }
2986 
2987 void KLocalePrivate::setMonetaryThousandsSeparator(const QString &separator)
2988 {
2989  // allow spaces here
2990  m_monetaryThousandsSeparator = separator;
2991 }
2992 
2993 void KLocalePrivate::setMonetaryDigitGrouping(QList<int> groupList)
2994 {
2995  m_monetaryDigitGrouping = groupList;
2996 }
2997 
2998 void KLocalePrivate::setMonetaryDecimalSymbol(const QString &symbol)
2999 {
3000  m_monetaryDecimalSymbol = symbol.trimmed();
3001 }
3002 
3003 void KLocalePrivate::setCurrencySymbol(const QString & symbol)
3004 {
3005  m_currencySymbol = symbol.trimmed();
3006 }
3007 
3008 int KLocalePrivate::pageSize() const
3009 {
3010  return m_pageSize;
3011 }
3012 
3013 void KLocalePrivate::setPageSize(int size)
3014 {
3015  // #### check if it's in range??
3016  m_pageSize = size;
3017 }
3018 
3019 KLocale::MeasureSystem KLocalePrivate::measureSystem() const
3020 {
3021  return m_measureSystem;
3022 }
3023 
3024 void KLocalePrivate::setMeasureSystem(KLocale::MeasureSystem value)
3025 {
3026  m_measureSystem = value;
3027 }
3028 
3029 QString KLocalePrivate::defaultLanguage()
3030 {
3031  static const QString en_US = QString::fromLatin1("en_US");
3032  return en_US;
3033 }
3034 
3035 QString KLocalePrivate::defaultCountry()
3036 {
3037  return QString::fromLatin1("C");
3038 }
3039 
3040 QString KLocalePrivate::defaultCurrencyCode()
3041 {
3042  return QString::fromLatin1("USD");
3043 }
3044 
3045 bool KLocalePrivate::useTranscript() const
3046 {
3047  return m_useTranscript;
3048 }
3049 
3050 const QByteArray KLocalePrivate::encoding()
3051 {
3052  return codecForEncoding()->name();
3053 }
3054 
3055 int KLocalePrivate::encodingMib() const
3056 {
3057  return codecForEncoding()->mibEnum();
3058 }
3059 
3060 int KLocalePrivate::fileEncodingMib() const
3061 {
3062  if (m_utf8FileEncoding) {
3063  return 106;
3064  }
3065  return codecForEncoding()->mibEnum();
3066 }
3067 
3068 QTextCodec *KLocalePrivate::codecForEncoding() const
3069 {
3070  return m_codecForEncoding;
3071 }
3072 
3073 bool 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 
3083 QStringList 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 
3091 QStringList 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 
3103 QString 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 
3113 QStringList 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 
3126 QString 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 
3138 KLocale::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 
3169 QString 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 
3201 void KLocalePrivate::setCalendar(const QString &calendarType)
3202 {
3203  setCalendarSystem(calendarTypeToCalendarSystem(calendarType));
3204 }
3205 
3206 void KLocalePrivate::setCalendarSystem(KLocale::CalendarSystem calendarSystem)
3207 {
3208  m_calendarSystem = calendarSystem;
3209  delete m_calendar;
3210  m_calendar = 0;
3211 }
3212 
3213 QString KLocalePrivate::calendarType() const
3214 {
3215  return calendarSystemToCalendarType(m_calendarSystem);
3216 }
3217 
3218 KLocale::CalendarSystem KLocalePrivate::calendarSystem() const
3219 {
3220  return m_calendarSystem;
3221 }
3222 
3223 const 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 
3232 void KLocalePrivate::setWeekNumberSystem(KLocale::WeekNumberSystem weekNumberSystem)
3233 {
3234  m_weekNumberSystem = weekNumberSystem;
3235 }
3236 
3237 KLocale::WeekNumberSystem KLocalePrivate::weekNumberSystem()
3238 {
3239  return m_weekNumberSystem;
3240 }
3241 
3242 void KLocalePrivate::copyCatalogsTo(KLocale *locale)
3243 {
3244  QMutexLocker lock(kLocaleMutex());
3245  locale->d->m_catalogNames = m_catalogNames;
3246  locale->d->updateCatalogs();
3247 }
3248 
3249 QString 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 
3282 QString KLocalePrivate::removeAcceleratorMarker(const QString &label) const
3283 {
3284  return ::removeAcceleratorMarker(label);
3285 }
3286 
3287 void KLocalePrivate::setDigitSet(KLocale::DigitSet digitSet)
3288 {
3289  m_digitSet = digitSet;
3290 }
3291 
3292 KLocale::DigitSet KLocalePrivate::digitSet() const
3293 {
3294  return m_digitSet;
3295 }
3296 
3297 void KLocalePrivate::setMonetaryDigitSet(KLocale::DigitSet digitSet)
3298 {
3299  m_monetaryDigitSet = digitSet;
3300 }
3301 
3302 KLocale::DigitSet KLocalePrivate::monetaryDigitSet() const
3303 {
3304  return m_monetaryDigitSet;
3305 }
3306 
3307 void KLocalePrivate::setDateTimeDigitSet(KLocale::DigitSet digitSet)
3308 {
3309  m_dateTimeDigitSet = digitSet;
3310 }
3311 
3312 KLocale::DigitSet KLocalePrivate::dateTimeDigitSet() const
3313 {
3314  return m_dateTimeDigitSet;
3315 }
3316 
3317 Q_GLOBAL_STATIC_WITH_ARGS(QMutex, s_kLocaleMutex, (QMutex::Recursive))
3318 
3319 QMutex *kLocaleMutex()
3320 {
3321  return s_kLocaleMutex();
3322 }
KDayPeriod::periodName
QString periodName(KLocale::DateTimeComponentFormat format=KLocale::ShortName) const
Return translated Period Name in the required format e.g.
Definition: kdayperiod.cpp:138
KLocale::TimeZone
Include a time zone string.
Definition: klocale.h:968
KLocale::AfterMoney
Suffix the currency symbol with the sign, e.g.
Definition: klocale.h:301
i18n
QString i18n(const char *text)
Returns a localized version of a string.
Definition: klocalizedstring.h:630
KLocalePrivate::setPositiveMonetarySignPosition
virtual void setPositiveMonetarySignPosition(KLocale::SignPosition signpos)
Definition: klocale_kde.cpp:2962
KSharedPtr< KSharedConfig >
KConfig::sync
void sync()
Definition: kconfig.cpp:414
KLocalePrivate::currencyCode
virtual QString currencyCode() const
Definition: klocale_kde.cpp:807
read3ConfigBoolEntry
#define read3ConfigBoolEntry(key, default, save)
KLocale::TimeFoldHours
Read/format time string as duration.
Definition: klocale.h:1030
KLocalePrivate::setEncoding
virtual bool setEncoding(int mibEnum)
Definition: klocale_kde.cpp:3073
KLocale::EthiopianCalendar
Ethiopian Calendar, aka Ethiopic Calendar.
Definition: klocale.h:786
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:40
KLocalePrivate::prettyFormatDuration
virtual QString prettyFormatDuration(unsigned long mSec) const
Definition: klocale_kde.cpp:1810
KLocalePrivate::monetaryDigitGrouping
virtual QList< int > monetaryDigitGrouping() const
Definition: klocale_kde.cpp:1247
stripAmPmFormat
static void stripAmPmFormat(QString &inout)
Definition: klocale_kde.cpp:2169
KLocale::ParensAround
Put parantheses around the quantity, e.g.
Definition: klocale.h:285
KLocalePrivate::formatNumber
virtual QString formatNumber(double num, int precision=-1) const
Definition: klocale_kde.cpp:1456
kdebug.h
KSharedPtr::data
T * data()
Definition: ksharedptr.h:111
KLocalePrivate::thousandsSeparator
virtual QString thousandsSeparator() const
Definition: klocale_kde.cpp:1222
kdatetime.h
Date/times with associated time zone.
KLocale::JapaneseCalendar
Japanese Calendar, Gregorian calculation using Japanese Era (Nengô)
Definition: klocale.h:799
KLocale::WithSeconds
Only accept a time string with seconds. Default (no flag set)
Definition: klocale.h:1298
KLocalePrivate::setDateTimeDigitSet
virtual void setDateTimeDigitSet(KLocale::DigitSet digitSet)
Definition: klocale_kde.cpp:3307
KLocalePrivate::systemCodeset
virtual QByteArray systemCodeset() const
Definition: klocale_kde.cpp:2649
KLocale::defaultCurrencyCode
static QString defaultCurrencyCode()
Definition: klocale.cpp:625
KLocalePrivate::readNumber
virtual double readNumber(const QString &numStr, bool *ok=0) const
Definition: klocale_kde.cpp:1863
KLocale::LastBinaryDialect
Definition: klocale.h:661
KLocalePrivate::formatSingleDuration
static QString formatSingleDuration(KLocalePrivate::DurationType durationType, int n)
Definition: klocale_kde.cpp:1795
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
put_it_in
static void put_it_in(QChar *buffer, int &index, const QString &s)
Definition: klocale_kde.cpp:1294
KLocalePrivate::setWorkingWeekStartDay
virtual void setWorkingWeekStartDay(int day)
Definition: klocale_kde.cpp:2895
KLocalePrivate::setDateMonthNamePossessive
virtual void setDateMonthNamePossessive(bool possessive)
Definition: klocale_kde.cpp:2878
KLocalePrivate::dateMonthNamePossessive
virtual bool dateMonthNamePossessive() const
Definition: klocale_kde.cpp:1187
KLocale::ProcessStrict
Process time in a strict manner, ie.
Definition: klocale.h:1326
KLocalePrivate::monetaryThousandsSeparator
virtual QString monetaryThousandsSeparator() const
Definition: klocale_kde.cpp:1242
KLocalePrivate::workingWeekEndDay
virtual int workingWeekEndDay() const
Definition: klocale_kde.cpp:1202
KLocalePrivate::monetaryDigitSet
virtual KLocale::DigitSet monetaryDigitSet() const
Definition: klocale_kde.cpp:3302
KLocalePrivate::measureSystem
virtual KLocale::MeasureSystem measureSystem() const
Definition: klocale_kde.cpp:3019
KLocalePrivate::init
virtual void init(const QString &catalogName, const QString &language, const QString &country, KSharedConfig::Ptr persistantconfig, KConfig *tempConfig)
Definition: klocale_kde.cpp:229
KDateTime::timeSpec
Spec timeSpec() const
Returns the time specification of the date/time, i.e.
Definition: kdatetime.cpp:842
KLocalePrivate::countryDivisionCode
QString countryDivisionCode() const
Definition: klocale_kde.cpp:790
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::TamilDigits
௦௧௨௩௪௫௬௭௮ (Tamil)
Definition: klocale.h:322
KLocalePrivate::useTranscript
virtual bool useTranscript() const
Definition: klocale_kde.cpp:3045
KLocalePrivate::monetaryDecimalSymbol
virtual QString monetaryDecimalSymbol() const
Definition: klocale_kde.cpp:1237
readConfigEntry
#define readConfigEntry(key, default, save)
KLocalePrivate::setCountryDivisionCode
bool setCountryDivisionCode(const QString &countryDivision)
Definition: klocale_kde.cpp:629
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
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:2085
KLocalePrivate::initMainCatalogs
virtual void initMainCatalogs()
Definition: klocale_kde.cpp:296
kconfig.h
KLocale::ShortDate
Locale Short date format, e.g.
Definition: klocale.h:923
KLocalePrivate::calendarTypeToCalendarSystem
virtual KLocale::CalendarSystem calendarTypeToCalendarSystem(const QString &calendarType) const
Definition: klocale_kde.cpp:3138
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
KLocalePrivate::toArabicDigits
static QString toArabicDigits(const QString &str)
Definition: klocale_kde.cpp:1169
KGlobal::dirs
KStandardDirs * dirs()
Returns the application standard dirs object.
stripStringAndSucceedingSeparator
static void stripStringAndSucceedingSeparator(QString &inout, const QLatin1String &strip2char)
Definition: klocale_kde.cpp:2153
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::copy
virtual void copy(const KLocalePrivate &rhs)
Definition: klocale_kde.cpp:139
KLocale::DateFormat
DateFormat
Format for date string.
Definition: klocale.h:922
KLocale::formatLocaleTime
QString formatLocaleTime(const QTime &pTime, TimeFormatOptions options=KLocale::TimeDefault) const
Definition: klocale.cpp:424
klocale_p.h
KLocalePrivate::localizedFilePath
virtual QString localizedFilePath(const QString &filePath) const
Definition: klocale_kde.cpp:3249
KLocale::GurmukhiDigits
੦੧੨੩੪੫੬੭੮੯ (Punjabi)
Definition: klocale.h:317
KLocalePrivate::splitLocale
static void splitLocale(const QString &locale, QString &language, QString &country, QString &modifier, QString &charset)
Definition: klocale_kde.cpp:742
KLocalePrivate::allDigitSetsList
virtual QList< KLocale::DigitSet > allDigitSetsList() const
Definition: klocale_kde.cpp:1034
KConfigBase::group
KConfigGroup group(const QByteArray &group)
Returns an object for the named subgroup.
Definition: kconfigbase.cpp:44
KDateTime::toString
QString toString(const QString &format) const
Returns the date/time as a string.
Definition: kdatetime.cpp:1434
KLocalePrivate::calendarSystemToCalendarType
virtual QString calendarSystemToCalendarType(KLocale::CalendarSystem) const
Definition: klocale_kde.cpp:3169
KLocalePrivate::decimalPlaces
virtual int decimalPlaces() const
Definition: klocale_kde.cpp:1212
KConfigGroup::writeEntry
void writeEntry(const QString &key, const QVariant &value, WriteConfigFlags pFlags=Normal)
Writes a value to the configuration object.
Definition: kconfiggroup.cpp:1038
KLocale::BeforeMoney
Prefix the currency symbol with the sign, e.g.
Definition: klocale.h:297
KLocale::AfterQuantityMoney
Suffix the quanitity with the sign, e.g.
Definition: klocale.h:293
KLocale::CopticCalendar
Coptic Calendar as used Coptic Church and some parts of Egypt.
Definition: klocale.h:785
kcalendarsystem.h
KLocalePrivate::langLookup
static QString langLookup(const QString &fname, const char *rtype="html")
Definition: klocale_kde.cpp:2589
KDateTime::isDateOnly
bool isDateOnly() const
Returns whether the instance represents a date/time or a date-only value.
Definition: kdatetime.cpp:832
KCatalogName
Definition: kcatalogname_p.h:25
KLocale::IECBinaryDialect
KDE Default, KiB, MiB, etc. 2^(10*n)
Definition: klocale.h:658
QString
KLocale::ThaiDigits
๐๑๒๓๔๕๖๗๘๙ (Thai)
Definition: klocale.h:324
_round
static void _round(QString &str, int precision)
Definition: klocale_kde.cpp:1515
QHash< KLocale::DigitSet, QStringList >
KLocalePrivate::~KLocalePrivate
virtual ~KLocalePrivate()
Destructor.
Definition: klocale_kde.cpp:220
KLocalePrivate::SecondsDurationType
Definition: klocale_p.h:982
removeAcceleratorMarker
QString removeAcceleratorMarker(const QString &label_)
Definition: common_helpers.cpp:52
KLocalePrivate::removeCatalog
virtual void removeCatalog(const QString &catalog)
Definition: klocale_kde.cpp:861
KLocale::HebrewCalendar
Hebrew Calendar, aka Jewish Calendar.
Definition: klocale.h:789
KLocalePrivate::convertDigits
virtual QString convertDigits(const QString &str, KLocale::DigitSet digitSet, bool ignoreContext=false) const
Definition: klocale_kde.cpp:1145
common_helpers_p.h
KLocale::BinarySizeUnits
BinarySizeUnits
These binary units are used in KDE by the formatByteSize() functions.
Definition: klocale.h:621
KLocalePrivate::dateFormatShort
virtual QString dateFormatShort() const
Definition: klocale_kde.cpp:2921
KLocalePrivate::initFileNameEncoding
virtual void initFileNameEncoding()
Definition: klocale_kde.cpp:2668
KLocalePrivate::setWorkingWeekEndDay
virtual void setWorkingWeekEndDay(int day)
Definition: klocale_kde.cpp:2902
KCatalogName::name
QString name
Definition: kcatalogname_p.h:28
KLocale::MalayalamDigits
൦൧൨൩൪൫൬൭൮൯ (Malayalam)
Definition: klocale.h:320
KLocalePrivate::digitSetToName
virtual QString digitSetToName(KLocale::DigitSet digitSet, bool withDigits=false) const
Definition: klocale_kde.cpp:1089
KCalendarSystem::create
static KCalendarSystem * create(const QString &calType=QLatin1String("gregorian"), const KLocale *locale=0)
Definition: kcalendarsystem.cpp:47
KLocalePrivate::initConfig
virtual void initConfig(KConfig *config)
Definition: klocale_kde.cpp:271
KLocalePrivate::encodeFileNameUTF8
static QByteArray encodeFileNameUTF8(const QString &fileName)
Definition: klocale_kde.cpp:2712
KLocale::TimeDuration
Read/format time string as duration.
Definition: klocale.h:1025
prefix
QString prefix()
Definition: kstandarddirs_win.cpp:28
KCalendarSystem
KCalendarSystem abstract base class, provides support for local Calendar Systems in KDE...
Definition: kcalendarsystem.h:40
i18nc
QString i18nc(const char *ctxt, const char *text)
Returns a localized version of a string and a context.
Definition: klocalizedstring.h:797
KLocalePrivate::setPositivePrefixCurrencySymbol
virtual void setPositivePrefixCurrencySymbol(bool prefix)
Definition: klocale_kde.cpp:2972
KGlobal::config
KSharedConfigPtr config()
Returns the general config object.
Definition: kglobal.cpp:138
KLocalePrivate::installedLanguages
virtual QStringList installedLanguages()
Definition: klocale_kde.cpp:3091
KLocalePrivate::config
KConfig * config()
Definition: klocale_kde.cpp:130
KLocalePrivate::setCalendarSystem
virtual void setCalendarSystem(KLocale::CalendarSystem)
Definition: klocale_kde.cpp:3206
KLocalePrivate::DurationType
DurationType
Definition: klocale_p.h:978
KLocalePrivate::formatByteSize
virtual QString formatByteSize(double size)
Definition: klocale_kde.cpp:1758
KLocalePrivate::initDayPeriods
virtual void initDayPeriods(const KConfigGroup &cg)
Definition: klocale_kde.cpp:568
isUnicodeNonCharacter
static bool isUnicodeNonCharacter(uint ucs4)
Definition: klocale_kde.cpp:2707
KConfigGroup::deleteEntry
void deleteEntry(const QString &pKey, WriteConfigFlags pFlags=Normal)
Deletes the entry specified by pKey in the current group.
Definition: kconfiggroup.cpp:1113
KLocale::IndianNationalCalendar
Indian National Calendar, not the Lunar Calendar.
Definition: klocale.h:794
KLocale::JEDECBinaryDialect
KDE 3.5 default, KB, MB, etc. 2^(10*n)
Definition: klocale.h:659
KCurrencyCode
Definition: kcurrencycode.h:45
readConfigNumEntry
#define readConfigNumEntry(key, default, save, type)
kglobal.h
KLocale::calendar
const KCalendarSystem * calendar() const
Returns a pointer to the calendar system object.
Definition: klocale.cpp:705
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:512
KLocale::DefaultBinaryUnits
Auto-choose a unit such that the result is in the range [0, 1000 or 1024)
Definition: klocale.h:623
KLocalePrivate::setMainCatalog
static void setMainCatalog(const char *catalog)
Definition: klocale_kde.cpp:1857
I18N_NOOP2_NOSTRIP
#define I18N_NOOP2_NOSTRIP(ctxt, text)
Definition: klocalizedstring.h:102
KLocalePrivate::setCalendar
virtual void setCalendar(const QString &calendarType)
Definition: klocale_kde.cpp:3201
KLocalePrivate::numericDigitGrouping
virtual QList< int > numericDigitGrouping() const
Definition: klocale_kde.cpp:1227
KLocale::ReadTimeFlags
ReadTimeFlags
Flags for the old version of readTime()
Definition: klocale.h:1297
KLocalePrivate::setMonetaryDecimalPlaces
virtual void setMonetaryDecimalPlaces(int digits)
Definition: klocale_kde.cpp:2982
KLocalePrivate::translateQt
virtual QString translateQt(const char *context, const char *sourceText, const char *comment) const
Definition: klocale_kde.cpp:973
KLocale::CalendarSystem
CalendarSystem
Definition: klocale.h:780
KLocalePrivate::language
virtual QString language() const
Definition: klocale_kde.cpp:780
KConfig::NoGlobals
Cascade to system settings, but omit user's globals.
Definition: kconfig.h:98
KLocalePrivate::formatLong
virtual QString formatLong(long num) const
Definition: klocale_kde.cpp:1465
KLocalePrivate::currencyCodeList
virtual QStringList currencyCodeList() const
Definition: klocale_kde.cpp:2499
KLocalePrivate::initCurrency
virtual void initCurrency()
Definition: klocale_kde.cpp:699
KLocalePrivate::setMonetaryDigitSet
virtual void setMonetaryDigitSet(KLocale::DigitSet digitSet)
Definition: klocale_kde.cpp:3297
KLocale::MinguoCalendar
Minguo Calendar, aka ROC, Republic of China or Taiwanese.
Definition: klocale.h:802
KConfig::setLocale
bool setLocale(const QString &aLocale)
Sets the locale to aLocale.
Definition: kconfig.cpp:731
KLocale::IsoWeekNumber
ISO Week Number.
Definition: klocale.h:817
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
KLocalePrivate::setActiveCatalog
virtual void setActiveCatalog(const QString &catalog)
Sets the active catalog for translation lookup.
Definition: klocale_kde.cpp:878
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
KLocale::JalaliCalendar
Jalali Calendar, aka Persian or Iranian, also used in Afghanistan.
Definition: klocale.h:796
KConfig::groupList
QStringList groupList() const
Definition: kconfig.cpp:291
KLocalePrivate::setNegativeSign
virtual void setNegativeSign(const QString &sign)
Definition: klocale_kde.cpp:2957
QStringList
KLocalePrivate::DaysDurationType
Definition: klocale_p.h:979
KLocalePrivate::allLanguagesList
virtual QStringList allLanguagesList()
Definition: klocale_kde.cpp:3083
KLocalePrivate::readTime
virtual QTime readTime(const QString &str, bool *ok=0) const
Definition: klocale_kde.cpp:2108
KLocalePrivate::pageSize
virtual int pageSize() const
Definition: klocale_kde.cpp:3008
KLocalePrivate::setCountry
virtual bool setCountry(const QString &country, KConfig *config)
Definition: klocale_kde.cpp:593
KLocalePrivate::currency
virtual KCurrencyCode * currency()
Definition: klocale_kde.cpp:799
KDateTime::date
QDate date() const
Returns the date part of the date/time.
Definition: kdatetime.cpp:838
KLocale::UnitYottaByte
YiB/YB/YB 2^80/10^24 bytes.
Definition: klocale.h:634
KDateTime::dateTime
QDateTime dateTime() const
Returns the date/time component of the instance, ignoring the time zone.
Definition: kdatetime.cpp:840
KLocalePrivate::weekDayOfPray
virtual int weekDayOfPray() const
Definition: klocale_kde.cpp:1207
KLocale::WeekNumberSystem
WeekNumberSystem
Definition: klocale.h:815
KLocale::MetricBinaryDialect
SI Units, kB, MB, etc. 10^(3*n)
Definition: klocale.h:660
KLocale::QDateCalendar
KDE Default, hybrid of Gregorian and Julian as used by QDate.
Definition: klocale.h:781
KLocale::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
KLocalePrivate::defaultLanguage
static QString defaultLanguage()
Definition: klocale_kde.cpp:3029
KLocalePrivate::readMoney
virtual double readMoney(const QString &numStr, bool *ok=0) const
Definition: klocale_kde.cpp:1950
KLocalePrivate::dayPeriods
virtual QList< KDayPeriod > dayPeriods() const
Definition: klocale_kde.cpp:2461
KLocalePrivate::setTimeFormat
virtual void setTimeFormat(const QString &format)
Definition: klocale_kde.cpp:2883
KSharedConfig::Ptr
KSharedPtr< KSharedConfig > Ptr
Definition: ksharedconfig.h:43
KLocale::OriyaDigits
୦୧୨୩୪୫୬୭୮୯ (Oriya)
Definition: klocale.h:321
KLocalePrivate::operator=
KLocalePrivate & operator=(const KLocalePrivate &rhs)
Assignment operator.
Definition: klocale_kde.cpp:124
KDateTime::ClockTime
a clock time which ignores time zones and simply uses whatever the local system clock says the time i...
Definition: kdatetime.h:203
KLocalePrivate::setWeekNumberSystem
void setWeekNumberSystem(KLocale::WeekNumberSystem weekNumberSystem)
Definition: klocale_kde.cpp:3232
KLocalePrivate::HoursDurationType
Definition: klocale_p.h:980
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
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::formatTime
virtual QString formatTime(const QTime &pTime, bool includeSecs=false, bool isDuration=false) const
Definition: klocale_kde.cpp:2329
KLocale::ReadDateFlags
ReadDateFlags
Flags for readDate()
Definition: klocale.h:1249
KLocalePrivate::digitSetString
static QString digitSetString(KLocale::DigitSet digitSet)
Definition: klocale_kde.cpp:1055
KLocalePrivate::setDecimalSymbol
virtual void setDecimalSymbol(const QString &symbol)
Definition: klocale_kde.cpp:2936
KLocalePrivate::copyCatalogsTo
virtual void copyCatalogsTo(KLocale *locale)
Definition: klocale_kde.cpp:3242
KLocale::TeluguDigits
౦౧౨౩౪౫౬౭౯ (Telugu)
Definition: klocale.h:323
KLocalePrivate::encoding
virtual const QByteArray encoding()
Definition: klocale_kde.cpp:3050
KLocalePrivate::setMeasureSystem
virtual void setMeasureSystem(KLocale::MeasureSystem value)
Definition: klocale_kde.cpp:3024
KLocalePrivate::positiveMonetarySignPosition
virtual KLocale::SignPosition positiveMonetarySignPosition() const
Definition: klocale_kde.cpp:1284
KLocale::GregorianCalendar
Gregorian Calendar, pure proleptic implementation.
Definition: klocale.h:788
KLocalePrivate::setMonetaryDigitGrouping
virtual void setMonetaryDigitGrouping(QList< int > groupList)
Definition: klocale_kde.cpp:2993
KLocale::BengaliDigits
০১২৩৪৫৬৭৮৯ (Bengali and Assamese)
Definition: klocale.h:315
KLocalePrivate::systemLanguageList
virtual QStringList systemLanguageList() const
Definition: klocale_kde.cpp:447
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
KLocalePrivate::negativeMonetarySignPosition
virtual KLocale::SignPosition negativeMonetarySignPosition() const
Definition: klocale_kde.cpp:1289
KLocalePrivate::country
virtual QString country() const
Definition: klocale_kde.cpp:785
KLocalePrivate::formatLocaleTime
virtual QString formatLocaleTime(const QTime &pTime, KLocale::TimeFormatOptions options=KLocale::TimeDefault) const
Definition: klocale_kde.cpp:2341
KLocalePrivate::languageCodeToName
virtual QString languageCodeToName(const QString &language)
Definition: klocale_kde.cpp:3103
KLocalePrivate::initLanguageList
virtual void initLanguageList(const QString &language, const QString &configLanguages, bool useEnv)
Definition: klocale_kde.cpp:402
KLocalePrivate::digitSet
virtual KLocale::DigitSet digitSet() const
Definition: klocale_kde.cpp:3292
KLocalePrivate::dateFormat
virtual QString dateFormat() const
Definition: klocale_kde.cpp:2916
KLocalePrivate::setLanguage
virtual bool setLanguage(const QString &language, KConfig *config)
Definition: klocale_kde.cpp:635
KLocalePrivate::readDate
virtual QDate readDate(const QString &str, bool *ok=0)
Definition: klocale_kde.cpp:2093
KLocalePrivate::systemCountry
virtual QString systemCountry() const
Definition: klocale_kde.cpp:393
KLocalePrivate::updateCatalogs
virtual void updateCatalogs()
Definition: klocale_kde.cpp:827
KCurrencyCode::decimalPlaces
int decimalPlaces() const
Return the number of decimal places required to display the currency subunits.
Definition: kcurrencycode.cpp:256
KDateTime
A class representing a date and time with an associated time zone.
Definition: kdatetime.h:171
KLocalePrivate::dialectUnitsList
QList< QString > dialectUnitsList(KLocale::BinaryUnitDialect dialect)
Definition: klocale_kde.cpp:1620
readInt
static int readInt(const QString &str, int &pos)
helper function to read integers
Definition: klocale_kde.cpp:2079
kWarning
#define kWarning
Definition: kdebug.h:322
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
KLocale::DefaultBinaryDialect
Used if no specific preference.
Definition: klocale.h:657
KConfigGroup::hasKey
bool hasKey(const QString &key) const
Checks whether the key has an entry in this group.
Definition: kconfiggroup.cpp:1156
kcatalog_p.h
KLocalePrivate::q
KLocale * q
Definition: klocale_p.h:1150
KLocale::ShortName
Short text format, e.g.
Definition: klocale.h:914
KLocalePrivate::KLocalePrivate
KLocalePrivate(KLocale *q_ptr)
Constructors.
Definition: klocale_kde.cpp:106
KLocalePrivate::setNumericDigitGrouping
virtual void setNumericDigitGrouping(QList< int > groupList)
Definition: klocale_kde.cpp:2947
KGlobal::locale
KLocale * locale()
Returns the global locale object.
Definition: kglobal.cpp:169
QDateTime
KLocale::TimeDefault
Default formatting using seconds and the format as specified by the locale.
Definition: klocale.h:1018
KConfigGroup
A class for one specific group in a KConfig object.
Definition: kconfiggroup.h:53
KLocalePrivate::weekStartDay
virtual int weekStartDay() const
Definition: klocale_kde.cpp:1192
KLocalePrivate::setDigitSet
virtual void setDigitSet(KLocale::DigitSet digitSet)
Definition: klocale_kde.cpp:3287
KCurrencyCode::isoCurrencyCode
QString isoCurrencyCode() const
Return the ISO 4217 Currency Code in Alpha 3 format, e.g.
Definition: kcurrencycode.cpp:167
KLocalePrivate::setCurrencyCode
virtual void setCurrencyCode(const QString &newCurrencyCode)
Definition: klocale_kde.cpp:711
kcatalogname_p.h
CACHE_BYTE_FMT
#define CACHE_BYTE_FMT(ctxt_text)
KLocalePrivate::getLanguagesFromVariable
static void getLanguagesFromVariable(QStringList &list, const char *variable, bool isLanguageList=false)
Definition: klocale_kde.cpp:329
KDateTime::OffsetFromUTC
a local time which has a fixed offset from UTC.
Definition: kdatetime.h:185
KConfig
The central class of the KDE configuration data system.
Definition: kconfig.h:70
KLocalePrivate::setCurrencySymbol
virtual void setCurrencySymbol(const QString &symbol)
Definition: klocale_kde.cpp:3003
KLocale::languageList
QStringList languageList() const
Returns the language codes selected by user, ordered by decreasing priority.
Definition: klocale.cpp:439
KLocalePrivate::setDayPeriods
virtual void setDayPeriods(const QList< KDayPeriod > &dayPeriods)
Definition: klocale_kde.cpp:2449
KLocalePrivate::setMonetaryThousandsSeparator
virtual void setMonetaryThousandsSeparator(const QString &separator)
Definition: klocale_kde.cpp:2987
KConfigGroup::config
KConfig * config()
Return the config object that this group belongs to.
Definition: kconfiggroup.cpp:610
kdayperiod_p.h
KLocale::FancyShortDate
Same as ShortDate for dates a week or more ago.
Definition: klocale.h:925
KCalendarSystem::readDate
virtual QDate readDate(const QString &str, bool *ok=0) const
Converts a localized date string to a QDate.
Definition: kcalendarsystem.cpp:2333
KLocalePrivate::negativePrefixCurrencySymbol
virtual bool negativePrefixCurrencySymbol() const
Definition: klocale_kde.cpp:1279
KLocalePrivate::initFormat
virtual void initFormat()
Reads the format configuration from disk.
Definition: klocale_kde.cpp:452
stripStringAndPreceedingSeparator
static void stripStringAndPreceedingSeparator(QString &inout, const QLatin1String &strip2char)
Definition: klocale_kde.cpp:2126
KDateTime::UTC
a UTC time.
Definition: kdatetime.h:184
KConfig::markAsClean
void markAsClean()
Definition: kconfig.cpp:484
KLocale
KLocale provides support for country specific stuff like the national language.
Definition: klocale.h:69
KLocalePrivate::defaultCurrencyCode
static QString defaultCurrencyCode()
Definition: klocale_kde.cpp:3040
KCurrencyCode::isValid
bool isValid() const
Return if the currency object loaded/initialised correctly.
Definition: kcurrencycode.cpp:266
kLocaleMutex
QMutex * kLocaleMutex()
Definition: klocale_kde.cpp:3319
KLocalePrivate::formatDuration
virtual QString formatDuration(unsigned long mSec) const
Definition: klocale_kde.cpp:1777
KLocalePrivate::calendar
virtual const KCalendarSystem * calendar()
Definition: klocale_kde.cpp:3223
klocalizedstring.h
KLocalePrivate::setDateFormat
virtual void setDateFormat(const QString &format)
Definition: klocale_kde.cpp:2868
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
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
KLocalePrivate::insertCatalog
virtual void insertCatalog(const QString &catalog)
Definition: klocale_kde.cpp:812
kstandarddirs.h
KLocalePrivate::nounDeclension
virtual bool nounDeclension() const
Definition: klocale_kde.cpp:1182
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::setNegativeMonetarySignPosition
virtual void setNegativeMonetarySignPosition(KLocale::SignPosition signpos)
Definition: klocale_kde.cpp:2967
KLocalePrivate::setPageSize
virtual void setPageSize(int paperFormat)
Definition: klocale_kde.cpp:3013
KLocale::EasternArabicIndicDigits
۰۱۲۳۴۵۶۷۸۹ (Persian and Urdu)
Definition: klocale.h:313
KLocalePrivate::positiveSign
virtual QString positiveSign() const
Definition: klocale_kde.cpp:1252
KLocalePrivate::negativeSign
virtual QString negativeSign() const
Definition: klocale_kde.cpp:1257
KLocale::TimeFormatOption
TimeFormatOption
Definition: klocale.h:1017
KLocalePrivate::setThousandsSeparator
virtual void setThousandsSeparator(const QString &separator)
Definition: klocale_kde.cpp:2941
KLocalePrivate::formatDateTime
static QString formatDateTime(const KLocale *locale, const QDateTime &dateTime, KLocale::DateFormat, bool includeSeconds, int daysToNow, int secsToNow)
Definition: klocale_kde.cpp:2504
KGlobal::hasMainComponent
bool hasMainComponent()
Definition: kglobal.cpp:150
KLocalePrivate::decimalSymbol
virtual QString decimalSymbol() const
Definition: klocale_kde.cpp:1217
KLocalePrivate::useDefaultLanguage
virtual bool useDefaultLanguage() const
Definition: klocale_kde.cpp:2618
KLocale::UnitLastUnit
Definition: klocale.h:635
KLocale::KannadaDigits
೦೧೨೩೪೫೬೭೮೯ (Kannada)
Definition: klocale.h:318
KDayPeriod
Definition: kdayperiod_p.h:54
KCatalog
This class abstracts a gettext message catalog.
Definition: kcatalog_p.h:35
KLocalePrivate::setDecimalPlaces
virtual void setDecimalPlaces(int digits)
Definition: klocale_kde.cpp:2931
KLocale::BeforeQuantityMoney
Prefix the quantity with the sign, e.g.
Definition: klocale.h:289
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
kDebug
#define kDebug
Definition: kdebug.h:316
KLocale::Seconds
Include the seconds value.
Definition: klocale.h:969
KLocale::LongDate
Locale Long date format, e.g.
Definition: klocale.h:924
KLocale::BinaryUnitDialect
BinaryUnitDialect
This enum chooses what dialect is used for binary units.
Definition: klocale.h:656
KLocalePrivate::setPositiveSign
virtual void setPositiveSign(const QString &sign)
Definition: klocale_kde.cpp:2952
KLocalePrivate::calendarSystem
KLocale::CalendarSystem calendarSystem() const
Definition: klocale_kde.cpp:3218
KLocalePrivate::encodingMib
virtual int encodingMib() const
Definition: klocale_kde.cpp:3055
KLocalePrivate::binaryUnitDialect
virtual KLocale::BinaryUnitDialect binaryUnitDialect() const
Definition: klocale_kde.cpp:1763
KLocalePrivate::use12Clock
virtual bool use12Clock() const
Definition: klocale_kde.cpp:2439
KLocalePrivate::allCountriesList
virtual QStringList allCountriesList() const
Definition: klocale_kde.cpp:3113
KLocale::DigitSet
DigitSet
Definition: klocale.h:309
kcurrencycode.h
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
KLocalePrivate::countryCodeToName
virtual QString countryCodeToName(const QString &country) const
Definition: klocale_kde.cpp:3126
KLocalePrivate::dayPeriodForTime
virtual KDayPeriod dayPeriodForTime(const QTime &time) const
Definition: klocale_kde.cpp:2482
KLocalePrivate::calendarType
virtual QString calendarType() const
Definition: klocale_kde.cpp:3213
KLocalePrivate::decodeFileNameUTF8
static QString decodeFileNameUTF8(const QByteArray &localFileName)
Definition: klocale_kde.cpp:2789
KLocalePrivate::formatDate
virtual QString formatDate(const QDate &date, KLocale::DateFormat format=KLocale::LongDate)
Definition: klocale_kde.cpp:1852
KLocalePrivate::setMonetaryDecimalSymbol
virtual void setMonetaryDecimalSymbol(const QString &symbol)
Definition: klocale_kde.cpp:2998
KLocale::FancyLongDate
Same as LongDate for dates a week or more ago.
Definition: klocale.h:928
kcomponentdata.h
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
KDayPeriod::isValid
bool isValid() const
Return if the Day Period is valid.
Definition: kdayperiod.cpp:186
KLocalePrivate::MinutesDurationType
Definition: klocale_p.h:981
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::ArabicDigits
0123456789 (European and some Asian languages and western Arabic dialects)
Definition: klocale.h:310
KLocalePrivate
Definition: klocale_p.h:34
KLocalePrivate::formatMoney
virtual QString formatMoney(double num, const QString &currency=QString(), int precision=-1) const
Definition: klocale_kde.cpp:1392
KLocale::Metric
Metric system (used e.g. in Europe)
Definition: klocale.h:1781
KLocale::KhmerDigits
០១២៣៤៥៦៧៨៩ (Khmer)
Definition: klocale.h:319
KLocale::ThaiCalendar
Thai Calendar, aka Buddhist or Thai Buddhist.
Definition: klocale.h:803
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
KLocalePrivate::workingWeekStartDay
virtual int workingWeekStartDay() const
Definition: klocale_kde.cpp:1197
KLocale::GujaratiDigits
૦૧૨૩૪૫૬૭૮૯ (Gujarati)
Definition: klocale.h:316
KLocale::ArabicIndicDigits
٠١٢٣٤٥٦٧٨٩ (eastern Arabic dialects)
Definition: klocale.h:312
KLocale::JulianCalendar
Julian Calendar, as used in Orthodox Churches.
Definition: klocale.h:801
KLocalePrivate::defaultCountry
static QString defaultCountry()
Definition: klocale_kde.cpp:3035
KLocale::DevenagariDigits
०१२३४५६७८९ (Hindi)
Definition: klocale.h:314
KDateTime::timeType
SpecType timeType() const
Returns the time specification type of the date/time, i.e.
Definition: kdatetime.cpp:843
KLocalePrivate::timeFormat
virtual QString timeFormat() const
Definition: klocale_kde.cpp:2926
KLocalePrivate::monetaryDecimalPlaces
virtual int monetaryDecimalPlaces() const
Definition: klocale_kde.cpp:1269
KLocalePrivate::setWeekDayOfPray
virtual void setWeekDayOfPray(int day)
Definition: klocale_kde.cpp:2909
KLocalePrivate::setNegativePrefixCurrencySymbol
virtual void setNegativePrefixCurrencySymbol(bool prefix)
Definition: klocale_kde.cpp:2977
KLocalePrivate::positivePrefixCurrencySymbol
virtual bool positivePrefixCurrencySymbol() const
Definition: klocale_kde.cpp:1274
KCalendarSystem::weekDayName
virtual QString weekDayName(int weekDay, WeekDayNameFormat format=LongDayName) const =0
Gets specific calendar type week day name.
Definition: kcalendarsystem.cpp:1881
KLocalePrivate::languageList
virtual QStringList languageList() const
Definition: klocale_kde.cpp:2494
KLocalePrivate::initCountry
virtual void initCountry(const QString &country, const QString &configCountry)
Definition: klocale_kde.cpp:359
KLocalePrivate::currencySymbol
virtual QString currencySymbol() const
Definition: klocale_kde.cpp:1232
KCurrencyCode::defaultSymbol
QString defaultSymbol() const
Return the default Symbol for the Currency, e.g.
Definition: kcurrencycode.cpp:218
KLocalePrivate::setDateFormatShort
virtual void setDateFormatShort(const QString &format)
Definition: klocale_kde.cpp:2873
KLocalePrivate::setWeekStartDay
virtual void setWeekStartDay(int day)
Definition: klocale_kde.cpp:2888
KLocalePrivate::dateTimeDigitSet
virtual KLocale::DigitSet dateTimeDigitSet() const
Definition: klocale_kde.cpp:3312
KLocalePrivate::isApplicationTranslatedInto
virtual bool isApplicationTranslatedInto(const QString &language)
Definition: klocale_kde.cpp:720
KLocale::defaultLanguage
static QString defaultLanguage()
Returns the name of the internal language.
Definition: klocale.cpp:615
KLocale::IslamicCivilCalendar
Islamic Civil Calendar, aka Hijri, not the Lunar Calendar.
Definition: klocale.h:792
kconfiggroup.h
KLocalePrivate::codecForEncoding
virtual QTextCodec * codecForEncoding() const
Definition: klocale_kde.cpp:3068
KDateTime::TimeZone
a time in a specified time zone.
Definition: kdatetime.h:186
QList< KCatalog >
KLocalePrivate::fileEncodingMib
virtual int fileEncodingMib() const
Definition: klocale_kde.cpp:3060
KLocalePrivate::removeAcceleratorMarker
virtual QString removeAcceleratorMarker(const QString &label) const
Definition: klocale_kde.cpp:3282
KLocalePrivate::weekNumberSystem
KLocale::WeekNumberSystem weekNumberSystem()
Definition: klocale_kde.cpp:3237
KLocalePrivate::setBinaryUnitDialect
virtual void setBinaryUnitDialect(KLocale::BinaryUnitDialect newDialect)
Definition: klocale_kde.cpp:1768
_inc_by_one
static void _inc_by_one(QString &str, int position)
Definition: klocale_kde.cpp:1471
KLocale::TimeWithoutSeconds
Exclude the seconds part of the time from display.
Definition: klocale.h:1020
KLocalePrivate::initEncoding
virtual void initEncoding()
Definition: klocale_kde.cpp:2623
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:47:08 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



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