Qt 4.8
qlocale_win.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qlocale_p.h"
43 #include "qlocale_tools_p.h"
44 
45 #include "qstringlist.h"
46 #include "qvariant.h"
47 #include "qdatetime.h"
48 
49 #include "private/qsystemlibrary_p.h"
50 
51 #include "qdebug.h"
52 
53 #if defined(Q_OS_WIN)
54 # include "qt_windows.h"
55 # include <time.h>
56 #endif
57 
59 
60 static QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT);
61 static const char *winLangCodeToIsoName(int code);
62 static QString winIso639LangName(LCID id = LOCALE_USER_DEFAULT);
63 static QString winIso3116CtryName(LCID id = LOCALE_USER_DEFAULT);
64 
65 #ifndef QT_NO_SYSTEMLOCALE
66 
67 #ifndef MUI_LANGUAGE_NAME
68 #define MUI_LANGUAGE_NAME 0x8
69 #endif
70 #ifndef LOCALE_SSHORTESTDAYNAME1
71 # define LOCALE_SSHORTESTDAYNAME1 0x0060
72 # define LOCALE_SSHORTESTDAYNAME2 0x0061
73 # define LOCALE_SSHORTESTDAYNAME3 0x0062
74 # define LOCALE_SSHORTESTDAYNAME4 0x0063
75 # define LOCALE_SSHORTESTDAYNAME5 0x0064
76 # define LOCALE_SSHORTESTDAYNAME6 0x0065
77 # define LOCALE_SSHORTESTDAYNAME7 0x0066
78 #endif
79 #ifndef LOCALE_SNATIVELANGUAGENAME
80 # define LOCALE_SNATIVELANGUAGENAME 0x00000004
81 #endif
82 #ifndef LOCALE_SNATIVECOUNTRYNAME
83 # define LOCALE_SNATIVECOUNTRYNAME 0x00000008
84 #endif
85 
87 {
89 
90  QChar zeroDigit();
104  QVariant amText();
105  QVariant pmText();
112 
113  void update();
114 
115 private:
117 
123  };
124 
125  // cached values:
126  LCID lcid;
129 
130  QString getLocaleInfo(LCTYPE type, int maxlen = 0);
131  int getLocaleInfo_int(LCTYPE type, int maxlen = 0);
133 
135  QString &substituteDigits(QString &string);
136 
137  static QString winToQtFormat(const QString &sys_fmt);
138 
139 };
140 Q_GLOBAL_STATIC(QSystemLocalePrivate, systemLocalePrivate)
141 
144 {
145  langEnvVar = qgetenv("LANG");
146  lcid = GetUserDefaultLCID();
147 }
148 
150 {
151  QVarLengthArray<wchar_t, 64> buf(maxlen ? maxlen : 64);
152  if (!GetLocaleInfo(lcid, type, buf.data(), buf.size()))
153  return QString();
154  if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
155  int cnt = GetLocaleInfo(lcid, type, 0, 0);
156  if (cnt == 0)
157  return QString();
158  buf.resize(cnt);
159  if (!GetLocaleInfo(lcid, type, buf.data(), buf.size()))
160  return QString();
161  }
162  return QString::fromWCharArray(buf.data());
163 }
164 
166 {
167  QString str = getLocaleInfo(type, maxlen);
168  bool ok = false;
169  int v = str.toInt(&ok);
170  return ok ? v : 0;
171 }
172 
174 {
175  QString str = getLocaleInfo(type);
176  return str.isEmpty() ? QChar() : str.at(0);
177 }
178 
180 {
181  if (substitutionType == SUnknown) {
182  wchar_t buf[8];
183  if (!GetLocaleInfo(lcid, LOCALE_IDIGITSUBSTITUTION, buf, 8)) {
185  return substitutionType;
186  }
187  if (buf[0] == '1')
189  else if (buf[0] == '0')
191  else if (buf[0] == '2')
193  else {
194  wchar_t digits[11];
195  if (!GetLocaleInfo(lcid, LOCALE_SNATIVEDIGITS, digits, 11)) {
197  return substitutionType;
198  }
199  const wchar_t zero = digits[0];
200  if (buf[0] == zero + 2)
202  else
204  }
205  }
206  return substitutionType;
207 }
208 
210 {
212  ushort *qch = (ushort *)string.data();
213  for (ushort *end = qch + string.size(); qch != end; ++qch) {
214  if (*qch >= '0' && *qch <= '9')
215  *qch = zero + (*qch - '0');
216  }
217  return string;
218 }
219 
221 {
222  if (zero.isNull())
223  zero = getLocaleInfo_qchar(LOCALE_SNATIVEDIGITS);
224  return zero;
225 }
226 
228 {
229  return getLocaleInfo_qchar(LOCALE_SDECIMAL);
230 }
231 
233 {
234  return getLocaleInfo_qchar(LOCALE_STHOUSAND);
235 }
236 
238 {
239  return getLocaleInfo_qchar(LOCALE_SNEGATIVESIGN);
240 }
241 
243 {
244  return getLocaleInfo_qchar(LOCALE_SPOSITIVESIGN);
245 }
246 
248 {
249  switch (type) {
251  return winToQtFormat(getLocaleInfo(LOCALE_SSHORTDATE));
252  case QLocale::LongFormat:
253  return winToQtFormat(getLocaleInfo(LOCALE_SLONGDATE));
255  break;
256  }
257  return QVariant();
258 }
259 
261 {
262  switch (type) {
264  return winToQtFormat(getLocaleInfo(LOCALE_STIMEFORMAT)); //###
265  case QLocale::LongFormat:
266  return winToQtFormat(getLocaleInfo(LOCALE_STIMEFORMAT));
268  break;
269  }
270  return QVariant();
271 }
272 
274 {
275  return QString(dateFormat(type).toString() + QLatin1Char(' ') + timeFormat(type).toString());
276 }
277 
279 {
280  static const LCTYPE short_day_map[]
281  = { LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2,
282  LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5,
283  LOCALE_SABBREVDAYNAME6, LOCALE_SABBREVDAYNAME7 };
284 
285  static const LCTYPE long_day_map[]
286  = { LOCALE_SDAYNAME1, LOCALE_SDAYNAME2,
287  LOCALE_SDAYNAME3, LOCALE_SDAYNAME4, LOCALE_SDAYNAME5,
288  LOCALE_SDAYNAME6, LOCALE_SDAYNAME7 };
289 
290  static const LCTYPE narrow_day_map[]
295 
296  day -= 1;
297 
298  if (type == QLocale::LongFormat)
299  return getLocaleInfo(long_day_map[day]);
301  return getLocaleInfo(narrow_day_map[day]);
302  return getLocaleInfo(short_day_map[day]);
303 }
304 
306 {
307  static const LCTYPE short_month_map[]
308  = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3,
309  LOCALE_SABBREVMONTHNAME4, LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
310  LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, LOCALE_SABBREVMONTHNAME9,
311  LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
312 
313  static const LCTYPE long_month_map[]
314  = { LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3,
315  LOCALE_SMONTHNAME4, LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6,
316  LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8, LOCALE_SMONTHNAME9,
317  LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12 };
318 
319  month -= 1;
320  if (month < 0 || month > 11)
321  return QString();
322 
323  LCTYPE lctype = (type == QLocale::ShortFormat || type == QLocale::NarrowFormat)
324  ? short_month_map[month] : long_month_map[month];
325  return getLocaleInfo(lctype);
326 }
327 
329 {
330  SYSTEMTIME st;
331  memset(&st, 0, sizeof(SYSTEMTIME));
332  st.wYear = date.year();
333  st.wMonth = date.month();
334  st.wDay = date.day();
335 
336  DWORD flags = (type == QLocale::LongFormat ? DATE_LONGDATE : DATE_SHORTDATE);
337  wchar_t buf[255];
338  if (GetDateFormat(lcid, flags, &st, NULL, buf, 255)) {
340  if (substitution() == SAlways)
341  substituteDigits(format);
342  return format;
343  }
344  return QString();
345 }
346 
348 {
349  SYSTEMTIME st;
350  memset(&st, 0, sizeof(SYSTEMTIME));
351  st.wHour = time.hour();
352  st.wMinute = time.minute();
353  st.wSecond = time.second();
354  st.wMilliseconds = 0;
355 
356  DWORD flags = 0;
357 
358  wchar_t buf[255];
359  if (GetTimeFormat(lcid, flags, &st, NULL, buf, 255)) {
361  if (substitution() == SAlways)
362  substituteDigits(format);
363  return format;
364  }
365  return QString();
366 }
367 
369 {
370  return QString(toString(dt.date(), type).toString() + QLatin1Char(' ') + toString(dt.time(), type).toString());
371 }
372 
374 {
375  wchar_t output[2];
376 
377  if (GetLocaleInfo(lcid, LOCALE_IMEASURE, output, 2)) {
378  QString iMeasure = QString::fromWCharArray(output);
379  if (iMeasure == QLatin1String("1")) {
381  }
382  }
383 
384  return QLocale::MetricSystem;
385 }
386 
388 {
389  wchar_t output[15]; // maximum length including terminating zero character for Win2003+
390 
391  if (GetLocaleInfo(lcid, LOCALE_S1159, output, 15)) {
392  return QString::fromWCharArray(output);
393  }
394 
395  return QVariant();
396 }
397 
399 {
400  wchar_t output[15]; // maximum length including terminating zero character for Win2003+
401 
402  if (GetLocaleInfo(lcid, LOCALE_S2359, output, 15)) {
403  return QString::fromWCharArray(output);
404  }
405 
406  return QVariant();
407 }
408 
410 {
411  wchar_t output[4]; // maximum length including terminating zero character for Win2003+
412 
413  if (GetLocaleInfo(lcid, LOCALE_IFIRSTDAYOFWEEK, output, 4))
414  return QString::fromWCharArray(output).toUInt()+1;
415 
416  return 1;
417 }
418 
420 {
421  wchar_t buf[13];
422  switch (format) {
424  if (GetLocaleInfo(lcid, LOCALE_SCURRENCY, buf, 13))
425  return QString::fromWCharArray(buf);
426  break;
428  if (GetLocaleInfo(lcid, LOCALE_SINTLSYMBOL, buf, 9))
429  return QString::fromWCharArray(buf);
430  break;
433  if (!GetLocaleInfo(lcid, LOCALE_SNATIVECURRNAME, buf.data(), buf.size())) {
434  if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
435  break;
436  buf.resize(255); // should be large enough, right?
437  if (!GetLocaleInfo(lcid, LOCALE_SNATIVECURRNAME, buf.data(), buf.size()))
438  break;
439  }
440  return QString::fromWCharArray(buf.data());
441  }
442  default:
443  break;
444  }
445  return QVariant();
446 }
447 
449 {
450  QString value;
451  switch (arg.value.type()) {
452  case QVariant::Int:
454  arg.value.toInt(), -1, 10, -1, QLocale::OmitGroupSeparator);
455  break;
456  case QVariant::UInt:
458  arg.value.toUInt(), -1, 10, -1, QLocale::OmitGroupSeparator);
459  break;
460  case QVariant::Double:
462  QLatin1Char(' '), QLatin1Char(','), QLatin1Char('.'),
464  break;
465  case QVariant::LongLong:
467  arg.value.toLongLong(), -1, 10, -1, QLocale::OmitGroupSeparator);
468  break;
469  case QVariant::ULongLong:
471  arg.value.toULongLong(), -1, 10, -1, QLocale::OmitGroupSeparator);
472  break;
473  default:
474  return QVariant();
475  }
476 
478 
479  QString decimalSep;
480  QString thousandSep;
481  CURRENCYFMT format;
482  CURRENCYFMT *pformat = NULL;
483  if (!arg.symbol.isEmpty()) {
484  format.NumDigits = getLocaleInfo_int(lcid, LOCALE_ICURRDIGITS);
485  format.LeadingZero = getLocaleInfo_int(lcid, LOCALE_ILZERO);
486  decimalSep = getLocaleInfo(lcid, LOCALE_SMONDECIMALSEP);
487  format.lpDecimalSep = (wchar_t *)decimalSep.utf16();
488  thousandSep = getLocaleInfo(lcid, LOCALE_SMONTHOUSANDSEP);
489  format.lpThousandSep = (wchar_t *)thousandSep.utf16();
490  format.NegativeOrder = getLocaleInfo_int(lcid, LOCALE_INEGCURR);
491  format.PositiveOrder = getLocaleInfo_int(lcid, LOCALE_ICURRENCY);
492  format.lpCurrencySymbol = (wchar_t *)arg.symbol.utf16();
493 
494  // grouping is complicated and ugly:
495  // int(0) == "123456789.00" == string("0")
496  // int(3) == "123,456,789.00" == string("3;0")
497  // int(30) == "123456,789.00" == string("3;0;0")
498  // int(32) == "12,34,56,789.00" == string("3;2;0")
499  // int(320)== "1234,56,789.00" == string("3;2")
500  QString groupingStr = getLocaleInfo(lcid, LOCALE_SMONGROUPING);
501  format.Grouping = groupingStr.remove(QLatin1Char(';')).toInt();
502  if (format.Grouping % 10 == 0) // magic
503  format.Grouping /= 10;
504  else
505  format.Grouping *= 10;
506  pformat = &format;
507  }
508 
509  int ret = ::GetCurrencyFormat(lcid, 0, reinterpret_cast<const wchar_t *>(value.utf16()),
510  pformat, out.data(), out.size());
511  if (ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
512  ret = ::GetCurrencyFormat(lcid, 0, reinterpret_cast<const wchar_t *>(value.utf16()),
513  pformat, out.data(), 0);
514  out.resize(ret);
515  ::GetCurrencyFormat(lcid, 0, reinterpret_cast<const wchar_t *>(value.utf16()),
516  pformat, out.data(), out.size());
517  }
518 
519  value = QString::fromWCharArray(out.data());
520  if (substitution() == SAlways)
521  substituteDigits( value);
522  return value;
523 }
524 
526 {
528  typedef BOOL (WINAPI *GetUserPreferredUILanguagesFunc) (
529  DWORD dwFlags,
530  PULONG pulNumLanguages,
531  PWSTR pwszLanguagesBuffer,
532  PULONG pcchLanguagesBuffer);
533  static GetUserPreferredUILanguagesFunc GetUserPreferredUILanguages_ptr = 0;
534  if (!GetUserPreferredUILanguages_ptr) {
535  QSystemLibrary lib(QLatin1String("kernel32"));
536  if (lib.load())
537  GetUserPreferredUILanguages_ptr = (GetUserPreferredUILanguagesFunc)lib.resolve("GetUserPreferredUILanguages");
538  }
539  if (GetUserPreferredUILanguages_ptr) {
540  unsigned long cnt = 0;
542  unsigned long size = buf.size();
543  if (!GetUserPreferredUILanguages_ptr(MUI_LANGUAGE_NAME, &cnt, buf.data(), &size)) {
544  size = 0;
545  if (GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
546  GetUserPreferredUILanguages_ptr(MUI_LANGUAGE_NAME, &cnt, NULL, &size)) {
547  buf.resize(size);
548  if (!GetUserPreferredUILanguages_ptr(MUI_LANGUAGE_NAME, &cnt, buf.data(), &size))
549  return QStringList();
550  }
551  }
552  QStringList result;
553  result.reserve(cnt);
554  const wchar_t *str = buf.constData();
555  for (; cnt > 0; --cnt) {
557  if (s.isEmpty())
558  break; // something is wrong
559  result.append(s);
560  str += s.size()+1;
561  }
562  return result;
563  }
564  }
565 
566  // old Windows before Vista
567  return QStringList(QString::fromLatin1(winLangCodeToIsoName(GetUserDefaultUILanguage())));
568 }
569 
571 {
573  return getLocaleInfo(LOCALE_SNATIVELANGNAME);
575 }
576 
578 {
580  return getLocaleInfo(LOCALE_SNATIVECTRYNAME);
582 }
583 
584 
586 {
587  lcid = GetUserDefaultLCID();
589  zero = QChar();
590 }
591 
593 {
594  QString result;
595  int i = 0;
596 
597  while (i < sys_fmt.size()) {
598  if (sys_fmt.at(i).unicode() == QLatin1Char('\'')) {
599  QString text = qt_readEscapedFormatString(sys_fmt, &i);
600  if (text == QLatin1String("'"))
601  result += QLatin1String("''");
602  else
603  result += QString(QLatin1Char('\'') + text + QLatin1Char('\''));
604  continue;
605  }
606 
607  QChar c = sys_fmt.at(i);
608  int repeat = qt_repeatCount(sys_fmt, i);
609 
610  switch (c.unicode()) {
611  // Date
612  case 'y':
613  if (repeat > 5)
614  repeat = 5;
615  else if (repeat == 3)
616  repeat = 2;
617  switch (repeat) {
618  case 1:
619  result += QLatin1String("yy"); // "y" unsupported by Qt, use "yy"
620  break;
621  case 5:
622  result += QLatin1String("yyyy"); // "yyyyy" same as "yyyy" on Windows
623  break;
624  default:
625  result += QString(repeat, QLatin1Char('y'));
626  break;
627  }
628  break;
629  case 'g':
630  if (repeat > 2)
631  repeat = 2;
632  switch (repeat) {
633  case 2:
634  break; // no equivalent of "gg" in Qt
635  default:
636  result += QLatin1Char('g');
637  break;
638  }
639  break;
640  case 't':
641  if (repeat > 2)
642  repeat = 2;
643  result += QLatin1String("AP"); // "t" unsupported, use "AP"
644  break;
645  default:
646  result += QString(repeat, c);
647  break;
648  }
649 
650  i += repeat;
651  }
652 
653  return result;
654 }
655 
657 {
659 }
660 
661 QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
662 {
663  QSystemLocalePrivate *d = systemLocalePrivate();
664  switch(type) {
665  case DecimalPoint:
666  return d->decimalPoint();
667  case GroupSeparator:
668  return d->groupSeparator();
669  case NegativeSign:
670  return d->negativeSign();
671  case PositiveSign:
672  return d->positiveSign();
673  case DateFormatLong:
674  return d->dateFormat(QLocale::LongFormat);
675  case DateFormatShort:
676  return d->dateFormat(QLocale::ShortFormat);
677  case TimeFormatLong:
678  return d->timeFormat(QLocale::LongFormat);
679  case TimeFormatShort:
680  return d->timeFormat(QLocale::ShortFormat);
681  case DateTimeFormatLong:
683  case DateTimeFormatShort:
685  case DayNameLong:
686  return d->dayName(in.toInt(), QLocale::LongFormat);
687  case DayNameShort:
688  return d->dayName(in.toInt(), QLocale::ShortFormat);
689  case MonthNameLong:
690  case StandaloneMonthNameLong:
691  return d->monthName(in.toInt(), QLocale::LongFormat);
692  case MonthNameShort:
693  case StandaloneMonthNameShort:
694  return d->monthName(in.toInt(), QLocale::ShortFormat);
695  case DateToStringShort:
696  return d->toString(in.toDate(), QLocale::ShortFormat);
697  case DateToStringLong:
698  return d->toString(in.toDate(), QLocale::LongFormat);
699  case TimeToStringShort:
700  return d->toString(in.toTime(), QLocale::ShortFormat);
701  case TimeToStringLong:
702  return d->toString(in.toTime(), QLocale::LongFormat);
703  case DateTimeToStringShort:
704  return d->toString(in.toDateTime(), QLocale::ShortFormat);
705  case DateTimeToStringLong:
706  return d->toString(in.toDateTime(), QLocale::LongFormat);
707  case ZeroDigit:
708  return d->zeroDigit();
709  case LanguageId:
710  case CountryId: {
712  QLocale::Language lang;
714  QLocale::Country cntry;
715  QLocalePrivate::getLangAndCountry(locale, lang, script, cntry);
716  if (type == LanguageId)
717  return lang;
718  if (cntry == QLocale::AnyCountry)
719  return fallbackLocale().country();
720  return cntry;
721  }
722  case ScriptId:
724  case MeasurementSystem:
725  return d->measurementSystem();
726  case AMText:
727  return d->amText();
728  case PMText:
729  return d->pmText();
730  case FirstDayOfWeek:
731  return d->firstDayOfWeek();
732  case CurrencySymbol:
733  return d->currencySymbol(QLocale::CurrencySymbolFormat(in.toUInt()));
734  case CurrencyToString:
736  case UILanguages:
737  return d->uiLanguages();
738  case LocaleChanged:
739  d->update();
740  break;
741  case NativeLanguageName:
742  return d->nativeLanguageName();
743  case NativeCountryName:
744  return d->nativeCountryName();
745  default:
746  break;
747  }
748  return QVariant();
749 }
750 #endif // QT_NO_SYSTEMLOCALE
751 
754  char iso_name[6];
755 };
756 
757 /* NOTE: This array should be sorted by the first column! */
759  { 0x0401, "ar_SA" },
760  { 0x0402, "bg\0 " },
761  { 0x0403, "ca\0 " },
762  { 0x0404, "zh_TW" },
763  { 0x0405, "cs\0 " },
764  { 0x0406, "da\0 " },
765  { 0x0407, "de\0 " },
766  { 0x0408, "el\0 " },
767  { 0x0409, "en_US" },
768  { 0x040a, "es\0 " },
769  { 0x040b, "fi\0 " },
770  { 0x040c, "fr\0 " },
771  { 0x040d, "he\0 " },
772  { 0x040e, "hu\0 " },
773  { 0x040f, "is\0 " },
774  { 0x0410, "it\0 " },
775  { 0x0411, "ja\0 " },
776  { 0x0412, "ko\0 " },
777  { 0x0413, "nl\0 " },
778  { 0x0414, "no\0 " },
779  { 0x0415, "pl\0 " },
780  { 0x0416, "pt_BR" },
781  { 0x0418, "ro\0 " },
782  { 0x0419, "ru\0 " },
783  { 0x041a, "hr\0 " },
784  { 0x041c, "sq\0 " },
785  { 0x041d, "sv\0 " },
786  { 0x041e, "th\0 " },
787  { 0x041f, "tr\0 " },
788  { 0x0420, "ur\0 " },
789  { 0x0421, "in\0 " },
790  { 0x0422, "uk\0 " },
791  { 0x0423, "be\0 " },
792  { 0x0425, "et\0 " },
793  { 0x0426, "lv\0 " },
794  { 0x0427, "lt\0 " },
795  { 0x0429, "fa\0 " },
796  { 0x042a, "vi\0 " },
797  { 0x042d, "eu\0 " },
798  { 0x042f, "mk\0 " },
799  { 0x0436, "af\0 " },
800  { 0x0438, "fo\0 " },
801  { 0x0439, "hi\0 " },
802  { 0x043e, "ms\0 " },
803  { 0x0458, "mt\0 " },
804  { 0x0801, "ar_IQ" },
805  { 0x0804, "zh_CN" },
806  { 0x0807, "de_CH" },
807  { 0x0809, "en_GB" },
808  { 0x080a, "es_MX" },
809  { 0x080c, "fr_BE" },
810  { 0x0810, "it_CH" },
811  { 0x0812, "ko\0 " },
812  { 0x0813, "nl_BE" },
813  { 0x0814, "no\0 " },
814  { 0x0816, "pt\0 " },
815  { 0x081a, "sr\0 " },
816  { 0x081d, "sv_FI" },
817  { 0x0c01, "ar_EG" },
818  { 0x0c04, "zh_HK" },
819  { 0x0c07, "de_AT" },
820  { 0x0c09, "en_AU" },
821  { 0x0c0a, "es\0 " },
822  { 0x0c0c, "fr_CA" },
823  { 0x0c1a, "sr\0 " },
824  { 0x1001, "ar_LY" },
825  { 0x1004, "zh_SG" },
826  { 0x1007, "de_LU" },
827  { 0x1009, "en_CA" },
828  { 0x100a, "es_GT" },
829  { 0x100c, "fr_CH" },
830  { 0x1401, "ar_DZ" },
831  { 0x1407, "de_LI" },
832  { 0x1409, "en_NZ" },
833  { 0x140a, "es_CR" },
834  { 0x140c, "fr_LU" },
835  { 0x1801, "ar_MA" },
836  { 0x1809, "en_IE" },
837  { 0x180a, "es_PA" },
838  { 0x1c01, "ar_TN" },
839  { 0x1c09, "en_ZA" },
840  { 0x1c0a, "es_DO" },
841  { 0x2001, "ar_OM" },
842  { 0x2009, "en_JM" },
843  { 0x200a, "es_VE" },
844  { 0x2401, "ar_YE" },
845  { 0x2409, "en\0 " },
846  { 0x240a, "es_CO" },
847  { 0x2801, "ar_SY" },
848  { 0x2809, "en_BZ" },
849  { 0x280a, "es_PE" },
850  { 0x2c01, "ar_JO" },
851  { 0x2c09, "en_TT" },
852  { 0x2c0a, "es_AR" },
853  { 0x3001, "ar_LB" },
854  { 0x300a, "es_EC" },
855  { 0x3401, "ar_KW" },
856  { 0x340a, "es_CL" },
857  { 0x3801, "ar_AE" },
858  { 0x380a, "es_UY" },
859  { 0x3c01, "ar_BH" },
860  { 0x3c0a, "es_PY" },
861  { 0x4001, "ar_QA" },
862  { 0x400a, "es_BO" },
863  { 0x440a, "es_SV" },
864  { 0x480a, "es_HN" },
865  { 0x4c0a, "es_NI" },
866  { 0x500a, "es_PR" }
867 };
868 
869 static const int windows_to_iso_count
871 
872 static const char *winLangCodeToIsoName(int code)
873 {
874  int cmp = code - windows_to_iso_list[0].windows_code;
875  if (cmp < 0)
876  return 0;
877 
878  if (cmp == 0)
879  return windows_to_iso_list[0].iso_name;
880 
881  int begin = 0;
883 
884  while (end - begin > 1) {
885  uint mid = (begin + end)/2;
886 
887  const WindowsToISOListElt *elt = windows_to_iso_list + mid;
888  int cmp = code - elt->windows_code;
889  if (cmp < 0)
890  end = mid;
891  else if (cmp > 0)
892  begin = mid;
893  else
894  return elt->iso_name;
895  }
896 
897  return 0;
898 
899 }
900 
901 static QString winIso639LangName(LCID id)
902 {
903  QString result;
904 
905  // Windows returns the wrong ISO639 for some languages, we need to detect them here using
906  // the language code
907  QString lang_code;
908  wchar_t out[256];
909  if (GetLocaleInfo(id, LOCALE_ILANGUAGE, out, 255)) // ### shouldn't use them according to msdn
910  lang_code = QString::fromWCharArray(out);
911 
912  if (!lang_code.isEmpty()) {
913  const char *endptr;
914  bool ok;
915  QByteArray latin1_lang_code = lang_code.toLatin1();
916  int i = qstrtoull(latin1_lang_code, &endptr, 16, &ok);
917  if (ok && *endptr == '\0') {
918  switch (i) {
919  case 0x814:
920  result = QLatin1String("nn"); // Nynorsk
921  break;
922  default:
923  break;
924  }
925  }
926  }
927 
928  if (!result.isEmpty())
929  return result;
930 
931  // not one of the problematic languages - do the usual lookup
932  if (GetLocaleInfo(id, LOCALE_SISO639LANGNAME , out, 255))
933  result = QString::fromWCharArray(out);
934 
935  return result;
936 }
937 
939 {
940  QString result;
941 
942  wchar_t out[256];
943  if (GetLocaleInfo(id, LOCALE_SISO3166CTRYNAME, out, 255))
944  result = QString::fromWCharArray(out);
945 
946  return result;
947 }
948 
950 {
951  QByteArray result;
952  if (id == LOCALE_USER_DEFAULT) {
953  static QByteArray langEnvVar = qgetenv("LANG");
954  result = langEnvVar;
955  QString lang, script, cntry;
956  if ( result == "C" || (!result.isEmpty()
957  && qt_splitLocaleName(QString::fromLocal8Bit(result), lang, script, cntry)) ) {
958  long id = 0;
959  bool ok = false;
960  id = qstrtoll(result.data(), 0, 0, &ok);
961  if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX )
962  return result;
963  else
964  return winLangCodeToIsoName( (int)id );
965  }
966  }
967 
968 #if defined(Q_OS_WINCE)
969  result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetUserDefaultLCID());
970 #else
971  if (id == LOCALE_USER_DEFAULT)
972  id = GetUserDefaultLCID();
973  QString resultuage = winIso639LangName(id);
975  result = resultuage.toLatin1();
976  if (!country.isEmpty()) {
977  result += '_';
978  result += country.toLatin1();
979  }
980 #endif
981 
982  return result;
983 }
984 
986 {
988 }
989 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static QString fromWCharArray(const wchar_t *, int size=-1)
Returns a copy of the string, where the encoding of string depends on the size of wchar...
Definition: qstring.cpp:1019
void resize(int size)
double d
Definition: qnumeric_p.h:62
QVariant measurementSystem()
const T * constData() const
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
static QString fromLocal8Bit(const char *, int size=-1)
Returns a QString initialized with the first size characters of the 8-bit string str.
Definition: qstring.cpp:4245
int type
Definition: qmetatype.cpp:239
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
#define LOCALE_SNATIVECOUNTRYNAME
Definition: qlocale_win.cpp:83
int getLocaleInfo_int(LCTYPE type, int maxlen=0)
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
static QString winIso639LangName(LCID id=LOCALE_USER_DEFAULT)
static const char * winLangCodeToIsoName(int code)
int toInt(bool *ok=0, int base=10) const
Returns the string converted to an int using base base, which is 10 by default and must be between 2 ...
Definition: qstring.cpp:6090
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
bool isNull() const
Returns true if the character is the Unicode character 0x0000 (&#39;\0&#39;); otherwise returns false...
Definition: qchar.h:262
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
int month() const
Returns the number corresponding to the month of this date, using the following convention: ...
Definition: qdatetime.cpp:382
FormatType
Definition: qlocale.h:659
static WinVersion windowsVersion()
Returns the version of the Windows operating system on which the application is run (Windows only)...
int day() const
Returns the day of the month (1 to 31) of this date.
Definition: qdatetime.cpp:395
The QDate class provides date functions.
Definition: qdatetime.h:55
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
bool qt_splitLocaleName(const QString &name, QString &lang, QString &script, QString &cntry)
Definition: qlocale.cpp:302
QVariant nativeLanguageName()
The QString class provides a Unicode character string.
Definition: qstring.h:83
QVariant currencySymbol(QLocale::CurrencySymbolFormat)
bool load(bool onlySystemDirectory=true)
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
static const WindowsToISOListElt windows_to_iso_list[]
static QString doubleToString(const QChar zero, const QChar plus, const QChar minus, const QChar exponent, const QChar group, const QChar decimal, double d, int precision, DoubleForm form, int width, unsigned flags)
Definition: qlocale.cpp:2613
int toInt(bool *ok=0) const
Returns the variant as an int if the variant has type() Int , Bool , ByteArray , Char ...
Definition: qvariant.cpp:2625
static void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Script &script, QLocale::Country &cntry)
Definition: qlocale.cpp:357
static QString unsLongLongToString(const QChar zero, const QChar group, const QChar plus, quint64 l, int precision, int base, int width, unsigned flags)
Definition: qlocale.cpp:2870
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
#define MUI_LANGUAGE_NAME
Definition: qlocale_win.cpp:68
int qt_repeatCount(const QString &s, int i)
Definition: qlocale.cpp:421
The QTime class provides clock time functions.
Definition: qdatetime.h:148
static QString longLongToString(const QChar zero, const QChar group, const QChar plus, const QChar minus, qint64 l, int precision, int base, int width, unsigned flags)
Definition: qlocale.cpp:2775
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
qlonglong toLongLong(bool *ok=0) const
Returns the variant as a long long int if the variant has type() LongLong , Bool , ByteArray , Char , Double , Int , String , UInt , or ULongLong ; otherwise returns 0.
Definition: qvariant.cpp:2659
#define LOCALE_SSHORTESTDAYNAME7
Definition: qlocale_win.cpp:77
QString qt_readEscapedFormatString(const QString &format, int *idx)
Definition: qlocale.cpp:387
#define LOCALE_SNATIVELANGUAGENAME
Definition: qlocale_win.cpp:80
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
#define LOCALE_SSHORTESTDAYNAME5
Definition: qlocale_win.cpp:75
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
qulonglong toULongLong(bool *ok=0) const
Returns the variant as as an unsigned long long int if the variant has type() ULongLong ...
Definition: qvariant.cpp:2675
int second() const
Returns the second part (0 to 59) of the time.
Definition: qdatetime.cpp:1600
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
QChar getLocaleInfo_qchar(LCTYPE type)
QVariant dateTimeFormat(QLocale::FormatType)
QVariant dateFormat(QLocale::FormatType)
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
static int cmp(const ushort *s1, const ushort *s2, size_t len)
QString getLocaleInfo(LCTYPE type, int maxlen=0)
int minute() const
Returns the minute part (0 to 59) of the time.
Definition: qdatetime.cpp:1589
Language
Definition: qlocale.h:148
QVariant timeFormat(QLocale::FormatType)
CurrencySymbolFormat
Specifies the format of the currency symbol.
Definition: qlocale.h:666
Q_CORE_EXPORT int QT_FASTCALL script(uint ucs4)
#define LOCALE_SSHORTESTDAYNAME1
Definition: qlocale_win.cpp:71
QVariant toCurrencyString(const QSystemLocale::CurrencyToStringArgument &)
qlonglong qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok)
static const int windows_to_iso_count
QDate date() const
Returns the date part of the datetime.
Definition: qdatetime.cpp:2357
#define LOCALE_SSHORTESTDAYNAME4
Definition: qlocale_win.cpp:74
#define LOCALE_SSHORTESTDAYNAME2
Definition: qlocale_win.cpp:72
SubstitutionType substitutionType
#define LOCALE_SSHORTESTDAYNAME3
Definition: qlocale_win.cpp:73
void * resolve(const char *symbol)
The QDateTime class provides date and time functions.
Definition: qdatetime.h:216
#define Q_CORE_EXPORT
Definition: qglobal.h:1449
static QString winIso3116CtryName(LCID id=LOCALE_USER_DEFAULT)
unsigned short ushort
Definition: qglobal.h:995
#define LOCALE_SSHORTESTDAYNAME6
Definition: qlocale_win.cpp:76
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
Type type() const
Returns the storage type of the value stored in the variant.
Definition: qvariant.cpp:1901
QVariant toString(const QDate &, QLocale::FormatType)
Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id)
#define st(var, type, card)
QVariant nativeCountryName()
uint toUInt(bool *ok=0) const
Returns the variant as an unsigned int if the variant has type() UInt , Bool , ByteArray ...
Definition: qvariant.cpp:2644
QVariant firstDayOfWeek()
uint toUInt(bool *ok=0, int base=10) const
Returns the string converted to an unsigned int using base base, which is 10 by default and must be b...
Definition: qstring.cpp:6120
QVariant dayName(int, QLocale::FormatType)
virtual QVariant query(QueryType type, QVariant in) const
qulonglong qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok)
double toDouble(bool *ok=0) const
Returns the variant as a double if the variant has type() Double , QMetaType::Float ...
Definition: qvariant.cpp:2710
virtual QLocale fallbackLocale() const
static QString winToQtFormat(const QString &sys_fmt)
QString & substituteDigits(QString &string)
int year() const
Returns the year of this date.
Definition: qdatetime.cpp:353
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
QTime time() const
Returns the time part of the datetime.
Definition: qdatetime.cpp:2368
QString & remove(int i, int len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition: qstring.cpp:1867
SubstitutionType substitution()
static const KeyPair *const end
QLocale::Country country
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
#define INT_MAX
QVariant monthName(int, QLocale::FormatType)
void reserve(int size)
Reserve space for alloc elements.
Definition: qlist.h:496
#define text
Definition: qobjectdefs.h:80
static QByteArray getWinLocaleName(LCID id=LOCALE_USER_DEFAULT)
int size() const
int hour() const
Returns the hour part (0 to 23) of the time.
Definition: qdatetime.cpp:1578
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290