summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qlocale.cpp797
-rw-r--r--src/corelib/tools/qlocale_symbian.cpp840
-rw-r--r--src/corelib/tools/tools.pri1
3 files changed, 844 insertions, 794 deletions
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index ee3e530..4d042ae 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -78,11 +78,6 @@ QT_END_NAMESPACE
#include <qdebug.h>
#include <time.h>
-#if defined(Q_OS_SYMBIAN)
-#include <e32std.h>
-#include "private/qcore_symbian_p.h"
-#endif
-
#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
# include <fenv.h>
#endif
@@ -303,7 +298,7 @@ static bool splitLocaleName(const QString &name, QChar *lang_begin, QChar *cntry
return lang_len == 2 || lang_len == 3;
}
-static void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Country &cntry)
+void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Country &cntry)
{
lang = QLocale::C;
cntry = QLocale::AnyCountry;
@@ -1282,794 +1277,8 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
}
return QVariant();
}
-#elif defined(Q_OS_SYMBIAN)
-
-static TExtendedLocale _s60Locale;
-
-// Type definitions for runtime resolved function pointers
-typedef void (*FormatFunc)(TTime&, TDes&, const TDesC&, const TLocale&);
-typedef TPtrC (*FormatSpecFunc)(TExtendedLocale&);
-
-// Runtime resolved functions
-static FormatFunc ptrTimeFormatL = NULL;
-static FormatSpecFunc ptrGetTimeFormatSpec = NULL;
-static FormatSpecFunc ptrGetLongDateFormatSpec = NULL;
-static FormatSpecFunc ptrGetShortDateFormatSpec = NULL;
-
-// Default functions if functions cannot be resolved
-static void defaultTimeFormatL(TTime&, TDes& des, const TDesC&, const TLocale&)
-{
- des.Zero();
-}
-
-static TPtrC defaultFormatSpec(TExtendedLocale&)
-{
- return TPtrC(KNullDesC);
-}
-
-/*!
- Definition of struct for mapping Symbian to ISO locale
-*/
-struct symbianToISO {
- int symbian_language;
- char iso_name[8];
-};
-
-/*!
- Mapping from Symbian to ISO locale
-*/
-static const symbianToISO symbian_to_iso_list[] = {
- { ELangEnglish, "en_GB" },
- { ELangFrench, "fr_FR" },
- { ELangGerman, "de_DE" },
- { ELangSpanish, "es_ES" },
- { ELangItalian, "it_IT" },
- { ELangSwedish, "sv_SE" },
- { ELangDanish, "da_DK" },
- { ELangNorwegian, "no_NO" },
- { ELangFinnish, "fi_FI" },
- { ELangAmerican, "en_US" },
- { ELangPortuguese, "pt_PT" },
- { ELangTurkish, "tr_TR" },
- { ELangIcelandic, "is_IS" },
- { ELangRussian, "ru_RU" },
- { ELangHungarian, "hu_HU" },
- { ELangDutch, "nl_NL" },
- { ELangBelgianFlemish, "nl_BE" },
- { ELangCzech, "cs_CZ" },
- { ELangSlovak, "sk_SK" },
- { ELangPolish, "pl_PL" },
- { ELangSlovenian, "sl_SI" },
- { ELangTaiwanChinese, "zh_TW" },
- { ELangHongKongChinese, "zh_HK" },
- { ELangPrcChinese, "zh_CN" },
- { ELangJapanese, "ja_JP" },
- { ELangThai, "th_TH" },
- { ELangArabic, "ar_AE" },
- { ELangTagalog, "tl_PH" },
- { ELangBulgarian, "bg_BG" },
- { ELangCatalan, "ca_ES" },
- { ELangCroatian, "hr_HR" },
- { ELangEstonian, "et_EE" },
- { ELangFarsi, "fa_IR" },
- { ELangCanadianFrench, "fr_CA" },
- { ELangGreek, "el_GR" },
- { ELangHebrew, "he_IL" },
- { ELangHindi, "hi_IN" },
- { ELangIndonesian, "id_ID" },
- { ELangLatvian, "lv_LV" },
- { ELangLithuanian, "lt_LT" },
- { ELangMalay, "ms_MY" },
- { ELangBrazilianPortuguese, "pt_BR" },
- { ELangRomanian, "ro_RO" },
- { ELangSerbian, "sr_YU" },
- { ELangLatinAmericanSpanish, "es" },
- { ELangUkrainian, "uk_UA" },
- { ELangUrdu, "ur_PK" }, // India/Pakistan
- { ELangVietnamese, "vi_VN" },
-#ifdef __E32LANG_H__
-// 5.0
- { ELangBasque, "eu_ES" },
- { ELangGalician, "gl_ES" },
-#endif
-#if !defined(__SERIES60_31__)
- { ELangEnglish_Apac, "en" },
- { ELangEnglish_Taiwan, "en_TW" },
- { ELangEnglish_HongKong, "en_HK" },
- { ELangEnglish_Prc, "en_CN" },
- { ELangEnglish_Japan, "en_JP"},
- { ELangEnglish_Thailand, "en_TH" },
- { ELangMalay_Apac, "ms" }
-#endif
-};
-
-/*!
- Returns ISO name corresponding to the Symbian locale code \a sys_fmt.
-*/
-static QByteArray symbianLocaleName(int code)
-{
- //Number of Symbian to ISO locale mappings
- static const int symbian_to_iso_count
- = sizeof(symbian_to_iso_list)/sizeof(symbianToISO);
-
- int cmp = code - symbian_to_iso_list[0].symbian_language;
- if (cmp < 0)
- return 0;
-
- if (cmp == 0)
- return symbian_to_iso_list[0].iso_name;
-
- int begin = 0;
- int end = symbian_to_iso_count;
-
- while (end - begin > 1) {
- uint mid = (begin + end)/2;
-
- const symbianToISO *elt = symbian_to_iso_list + mid;
- int cmp = code - elt->symbian_language;
- if (cmp < 0)
- end = mid;
- else if (cmp > 0)
- begin = mid;
- else
- return elt->iso_name;
- }
-
- return 0;
-}
-
-
-// order is: normal, abbr, nmode, nmode+abbr
-static const char *us_locale_dep[] = {
- "MM", "dd", "yyyy", "MM", "dd",
- "M", "d", "yy", "M", "d",
- "MMMM", "dd", "yyyy", "MMMM", "dd",
- "MMM", "d", "yy", "MMM", "d" };
-
-static const char *eu_locale_dep[] = {
- "dd", "MM", "yyyy", "dd", "MM",
- "d", "M", "yy", "d", "M",
- "dd", "MMMM", "yyyy", "dd", "MMMM",
- "d", "MMM", "yy", "d", "MMM" };
-
-static const char *jp_locale_dep[] = {
- "yyyy", "MM", "dd", "MM", "dd",
- "yy", "M", "d", "M", "d",
- "yyyy", "MMMM", "dd", "MMMM", "dd",
- "yy", "MMM", "d", "MMM", "d" };
-
-/*!
- Returns a Qt version of the given \a sys_fmt Symbian locale format string.
-*/
-static QString s60ToQtFormat(const QString &sys_fmt)
-{
- TLocale *locale = _s60Locale.GetLocale();
-
- QString result;
- QString other;
- QString qtformatchars = QString::fromLatin1("adhmsyzAHM");
-
- QChar c;
- int i = 0;
- bool open_escape = false;
- bool abbrev_next = false;
- bool locale_indep_ordering = false;
- bool minus_mode = false;
- bool plus_mode = false;
- bool n_mode = false;
- TTimeFormat tf = locale->TimeFormat();
-
- while (i < sys_fmt.size()) {
-
- c = sys_fmt.at(i);
-
- // let formatting thru
- if (c.unicode() == '%') {
- // if we have gathered string, concat it
- if (!other.isEmpty()) {
- result += other;
- other.clear();
- }
- // if we have open escape, end it
- if (open_escape) {
- result += QLatin1Char('\'');
- open_escape = false;
- }
-
- ++i;
- if (i >= sys_fmt.size())
- break;
-
- c = sys_fmt.at(i);
-
- // process specials
- abbrev_next = c.unicode() == '*';
- plus_mode = c.unicode() == '+';
- minus_mode = c.unicode() == '-';
-
- if (abbrev_next || plus_mode || minus_mode) {
- ++i;
- if (i >= sys_fmt.size())
- break;
-
- c = sys_fmt.at(i);
-
- if (plus_mode || minus_mode) {
- // break on undefined plus/minus mode
- if (c.unicode() != 'A' && c.unicode() != 'B')
- break;
- }
- }
-
- switch (c.unicode()) {
- case 'F':
- // locale indep mode on
- locale_indep_ordering = true;
- break;
-
- case '/':
- // date sep 0-3
- ++i;
- if (i >= sys_fmt.size())
- break;
-
- c = sys_fmt.at(i);
- if (c.isDigit() && c.digitValue() <= 3) {
- TChar s = locale->DateSeparator(c.digitValue());
- TUint val = s;
- // some indexes return zero for empty
- if (val > 0)
- result += QChar(val);
- }
- break;
-
- case 'D':
- if (!locale_indep_ordering)
- break;
-
- if (!abbrev_next)
- result += QLatin1String("dd");
- else
- result += QLatin1Char('d');
-
- break;
-
- case 'M':
- if (!locale_indep_ordering)
- break;
-
- if (!n_mode) {
- if (!abbrev_next)
- result += QLatin1String("MM");
- else
- result += QLatin1String("M");
- } else {
- if (!abbrev_next)
- result += QLatin1String("MMMM");
- else
- result += QLatin1String("MMM");
- }
-
- break;
-
- case 'N':
- n_mode = true;
-
- if (!locale_indep_ordering)
- break;
-
- if (!abbrev_next)
- result += QLatin1String("MMMM");
- else
- result += QLatin1String("MMM");
-
- break;
-
- case 'Y':
- if (!locale_indep_ordering)
- break;
-
- if (!abbrev_next)
- result += QLatin1String("yyyy");
- else
- result += QLatin1String("yy");
-
- break;
-
- case 'E':
- if (!abbrev_next)
- result += QLatin1String("dddd");
- else
- result += QLatin1String("ddd");
-
- break;
-
- case ':':
- // timesep 0-3
- ++i;
- if (i >= sys_fmt.size())
- break;
-
- c = sys_fmt.at(i);
- if (c.isDigit() && c.digitValue() <= 3) {
- TChar s = locale->TimeSeparator(c.digitValue());
- TUint val = s;
- // some indexes return zero for empty
- if (val > 0)
- result += QChar(val);
- }
-
- break;
-
- case 'J':
- if (tf == ETime24 && !abbrev_next)
- result += QLatin1String("hh");
- else
- result += QLatin1Char('h');
-
- break;
-
- case 'H':
- if (!abbrev_next)
- result += QLatin1String("hh");
- else
- result += QLatin1Char('h');
-
- break;
-
- case 'I':
- result += QLatin1Char('h');
- break;
-
- case 'T':
- if (!abbrev_next)
- result += QLatin1String("mm");
- else
- result += QLatin1Char('m');
-
- break;
-
- case 'S':
- if (!abbrev_next)
- result += QLatin1String("ss");
- else
- result += QLatin1Char('s');
-
- break;
-
- case 'B':
- // only done for 12h clock
- if (tf == ETime24)
- break;
-
- // fallthru to A
- case 'A': {
- // quickie to get capitalization, can't use s60 string as is because Qt 'hh' format's am/pm logic
- TAmPmName ampm = TAmPmName();
- TChar first(ampm[0]);
- QString qtampm = QString::fromLatin1(first.IsUpper() ? "AP" : "ap");
-
- int pos = locale->AmPmSymbolPosition();
-
- if ((minus_mode && pos != ELocaleBefore) ||
- (plus_mode && pos != ELocaleAfter))
- break;
-
- if (!abbrev_next && locale->AmPmSpaceBetween()) {
- if (pos == ELocaleBefore)
- qtampm.append(QLatin1Char(' '));
- else
- qtampm.prepend(QLatin1Char(' '));
- }
-
- result += qtampm;
- }
- break;
-
- case '.': {
- // decimal sep
- TChar s = locale->DecimalSeparator();
- TUint val = s;
- if (val > 0)
- result += QChar(val);
- }
- break;
-
- case 'C':
- // six digits in s60, three digits in qt
- if (!abbrev_next) {
- result += QLatin1String("zzz");
- } else {
- // next char is number from 0-6, how many digits to display
- ++i;
- if (i >= sys_fmt.size())
- break;
-
- c = sys_fmt.at(i);
-
- if (c.isDigit()) {
- // try to match wanted digits
- QChar val(c.digitValue());
-
- if (val >= 3) {
- result += QLatin1String("zzz");
- } else if (val > 0) {
- result += QLatin1Char('z');
- }
- }
- }
- break;
-
- // these cases fallthru
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
-
- // shouldn't parse these with %F
- if (locale_indep_ordering)
- break;
-
- TDateFormat df = locale->DateFormat();
-
- const char **locale_dep;
- switch (df) {
- default: // fallthru to american
- case EDateAmerican:
- locale_dep = us_locale_dep;
- break;
- case EDateEuropean:
- locale_dep = eu_locale_dep;
- break;
- case EDateJapanese:
- locale_dep = jp_locale_dep;
- break;
- }
- int offset = 0;
- if (abbrev_next)
- offset += 5;
- if (n_mode)
- offset += 10;
-
- result += QLatin1String(locale_dep[offset + (c.digitValue()-1)]);
- break;
-
- case '%': // fallthru percent
- // any junk gets copied as is
- default:
- result += c;
- break;
-
- case 'Z': // Qt doesn't support these :(
- case 'X':
- case 'W':
- break;
- }
- } else {
- // double any single quotes, don't begin escape
- if (c.unicode() == '\'') {
- // end open escape
- if (open_escape) {
- result += other;
- other.clear();
- result += QLatin1Char('\'');
- open_escape = false;
- }
-
- other += c;
- }
-
- // gather chars and escape them in one go if any format chars are found
- if (!open_escape && qtformatchars.indexOf(c) != -1) {
- result += QLatin1Char('\'');
- open_escape = true;
- }
- other += c;
- }
-
- ++i;
- }
-
- if (!other.isEmpty())
- result += other;
- if (open_escape)
- result += QLatin1Char('\'');
-
- return result;
-}
-
-/*!
- Retrieves Symbian locale decimal separator.
-*/
-static QString symbianDecimalPoint()
-{
- TLocale *locale = _s60Locale.GetLocale();
-
- TChar decPoint = locale->DecimalSeparator();
- int val = decPoint;
- return QChar(val);
-}
-
-/*!
- Retrieves Symbian locale group separator.
-*/
-static QString symbianGroupSeparator()
-{
- TLocale *locale = _s60Locale.GetLocale();
-
- TChar grpSep = locale->ThousandsSeparator();
- int val = grpSep;
- return QChar(val);
-}
-
-/*!
- Retrieves Symbian locale zero digit.
-*/
-static QString symbianZeroDigit()
-{
- TLocale *locale = _s60Locale.GetLocale();
-
- // TDigitType enumeration value returned by TLocale
- // will always correspond to zero digit unicode value.
- TDigitType digit = locale->DigitType();
- return QChar(digit);
-}
-
-/*!
- Retrieves a day name from Symbian locale. The \a day is an integer
- from 1 to 7. When \a short_format is true the method returns
- the day in short format. Otherwise it returns the day in a long format.
-*/
-static QString symbianDayName(int day, bool short_format)
-{
- day -= 1;
-
- if (day < 0 || day > 6)
- return QString();
-
- if (short_format) {
- return qt_TDes2QStringL(TDayNameAbb(TDay(day)));
- } else {
- return qt_TDes2QStringL(TDayName(TDay(day)));
- }
-}
-
-/*!
- Retrieves a month name from Symbian locale. The \a month is an integer
- from 1 to 12. When \a short_format is true the method returns
- the month in short format. Otherwise it returns the month in a long format.
-*/
-static QString symbianMonthName(int month, bool short_format)
-{
- month -= 1;
- if (month < 0 || month > 11)
- return QString();
-
- if (short_format) {
- return qt_TDes2QStringL(TMonthNameAbb(TMonth(month)));
- } else {
- return qt_TDes2QStringL(TMonthName(TMonth(month)));
- }
-}
-
-/*!
- Retrieves date format from Symbian locale and
- transforms it to Qt format.
-
- When \a short_format is true the method returns
- short date format. Otherwise it returns the long format.
-*/
-static QString symbianDateFormat(bool short_format)
-{
- TPtrC dateFormat;
-
- if (short_format) {
- dateFormat.Set(ptrGetShortDateFormatSpec(_s60Locale));
- } else {
- dateFormat.Set(ptrGetLongDateFormatSpec(_s60Locale));
- }
-
- return s60ToQtFormat(qt_TDesC2QStringL(dateFormat));
-}
-
-/*!
- Retrieves time format from Symbian locale and
- transforms it to Qt format.
-*/
-static QString symbianTimeFormat()
-{
- return s60ToQtFormat(qt_TDesC2QStringL(ptrGetTimeFormatSpec(_s60Locale)));
-}
-
-/*!
- Returns localized string representation of given \a date
- formatted with Symbian locale date format.
-
- If \a short_format is true the format will be a short version.
- Otherwise it uses a longer version.
-*/
-static QString symbianDateToString(const QDate &date, bool short_format)
-{
- int month = date.month() - 1;
- int day = date.day() - 1;
- int year = date.year();
-
- TDateTime dateTime;
- dateTime.Set(year, TMonth(month), day, 0, 0, 0, 0);
-
- TTime timeStr(dateTime);
- TBuf<KMaxLongDateFormatSpec*2> buffer;
-
- TPtrC dateFormat;
- if (short_format) {
- dateFormat.Set(ptrGetShortDateFormatSpec(_s60Locale));
- } else {
- dateFormat.Set(ptrGetLongDateFormatSpec(_s60Locale));
- }
-
- TRAPD(err, ptrTimeFormatL(timeStr, buffer, dateFormat, *_s60Locale.GetLocale());)
-
- if (err == KErrNone)
- return qt_TDes2QStringL(buffer);
- else
- return QString();
-}
-
-/*!
- Returns localized string representation of given \a time
- formatted with Symbian locale time format.
-*/
-static QString symbianTimeToString(const QTime &time)
-{
- int hour = time.hour();
- int minute = time.minute();
- int second = time.second();
- int milliseconds = 0;
-
- TDateTime dateTime;
- dateTime.Set(0, TMonth(0), 0, hour, minute, second, milliseconds);
-
- TTime timeStr(dateTime);
- TBuf<KMaxTimeFormatSpec*2> buffer;
-
- TRAPD(err, ptrTimeFormatL(
- timeStr,
- buffer,
- ptrGetTimeFormatSpec(_s60Locale),
- *_s60Locale.GetLocale());
- )
-
- if (err == KErrNone)
- return qt_TDes2QStringL(buffer);
- else
- return QString();
-}
-
-/*!
- Returns the measurement system stored in Symbian locale
-
- \sa QLocale::MeasurementSystem
-*/
-static QLocale::MeasurementSystem symbianMeasurementSystem()
-{
- TLocale *locale = _s60Locale.GetLocale();
-
- TUnitsFormat unitFormat = locale->UnitsGeneral();
- if (unitFormat == EUnitsImperial)
- return QLocale::ImperialSystem;
- else
- return QLocale::MetricSystem;
-}
-
-QLocale QSystemLocale::fallbackLocale() const
-{
- // load system data before query calls
- static bool initDone = false;
- if (!initDone) {
- _s60Locale.LoadSystemSettings();
-
- // Initialize platform version dependent function pointers
- ptrTimeFormatL = reinterpret_cast<FormatFunc>
- (qt_resolveS60PluginFunc(S60Plugin_TimeFormatL));
- ptrGetTimeFormatSpec = reinterpret_cast<FormatSpecFunc>
- (qt_resolveS60PluginFunc(S60Plugin_GetTimeFormatSpec));
- ptrGetLongDateFormatSpec = reinterpret_cast<FormatSpecFunc>
- (qt_resolveS60PluginFunc(S60Plugin_GetLongDateFormatSpec));
- ptrGetShortDateFormatSpec = reinterpret_cast<FormatSpecFunc>
- (qt_resolveS60PluginFunc(S60Plugin_GetShortDateFormatSpec));
- if (!ptrTimeFormatL)
- ptrTimeFormatL = &defaultTimeFormatL;
- if (!ptrGetTimeFormatSpec)
- ptrGetTimeFormatSpec = &defaultFormatSpec;
- if (!ptrGetLongDateFormatSpec)
- ptrGetLongDateFormatSpec = &defaultFormatSpec;
- if (!ptrGetShortDateFormatSpec)
- ptrGetShortDateFormatSpec = &defaultFormatSpec;
- }
-
- TLanguage lang = User::Language();
- QString locale = symbianLocaleName(lang);
- return QLocale(locale);
-}
-
-/*!
- Generic query method for locale data. Provides indirection.
- Denotes the \a type of the query
- with \a in as input data depending on the query.
-
- \sa QSystemLocale::QueryType
-*/
-QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
-{
- switch(type) {
- case DecimalPoint:
- return symbianDecimalPoint();
- case GroupSeparator:
- return symbianGroupSeparator();
-
- case ZeroDigit:
- return symbianZeroDigit();
-
- case DayNameLong:
- case DayNameShort:
- return symbianDayName(in.toInt(), (type == DayNameShort) );
-
- case MonthNameLong:
- case MonthNameShort:
- return symbianMonthName(in.toInt(), (type == MonthNameShort) );
-
- case DateFormatLong:
- case DateFormatShort:
- return symbianDateFormat( (type == DateFormatShort) );
- case TimeFormatLong:
- case TimeFormatShort:
- return symbianTimeFormat();
- case DateTimeFormatLong:
- case DateTimeFormatShort:
- return symbianDateFormat( (type == DateTimeFormatShort) ) + QLatin1Char(' ') + symbianTimeFormat();
- case DateToStringShort:
- case DateToStringLong:
- return symbianDateToString(in.toDate(), (type == DateToStringShort) );
- case TimeToStringShort:
- case TimeToStringLong:
- return symbianTimeToString(in.toTime());
- case DateTimeToStringShort:
- case DateTimeToStringLong: {
- const QDateTime dt = in.toDateTime();
- return symbianDateToString(dt.date(), (type == DateTimeToStringShort) )
- + QLatin1Char(' ') + symbianTimeToString(dt.time());
- }
- case MeasurementSystem:
- return static_cast<int>(symbianMeasurementSystem());
- case LanguageId:
- case CountryId: {
- TLanguage language = User::Language();
- QString locale = symbianLocaleName(language);
- QLocale::Language lang;
- QLocale::Country cntry;
- getLangAndCountry(locale, lang, cntry);
- if (type == LanguageId)
- return lang;
- // few iso codes have no country and will use this
- if (cntry == QLocale::AnyCountry)
- return fallbackLocale().country();
-
- return cntry;
- }
- case NegativeSign:
- case PositiveSign:
- case AMText:
- case PMText:
- break;
- default:
- break;
- }
- return QVariant();
-}
-
-#elif defined(Q_OS_UNIX)
+#elif defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
static uint unixGetSystemMeasurementSystem()
{
@@ -2113,7 +1322,7 @@ QVariant QSystemLocale::query(QueryType type, QVariant /* in */) const
}
}
-#else
+#elif !defined(Q_OS_SYMBIAN)
/*!
Returns a fallback locale, that will get used for everything that
diff --git a/src/corelib/tools/qlocale_symbian.cpp b/src/corelib/tools/qlocale_symbian.cpp
new file mode 100644
index 0000000..b58a5d5
--- /dev/null
+++ b/src/corelib/tools/qlocale_symbian.cpp
@@ -0,0 +1,840 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDate>
+#include <QLocale>
+#include <QTime>
+#include <QVariant>
+
+#include <e32std.h>
+#include "private/qcore_symbian_p.h"
+
+// Located in qlocale.cpp
+extern void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Country &cntry);
+
+QT_BEGIN_NAMESPACE
+
+static TExtendedLocale _s60Locale;
+
+// Type definitions for runtime resolved function pointers
+typedef void (*FormatFunc)(TTime&, TDes&, const TDesC&, const TLocale&);
+typedef TPtrC (*FormatSpecFunc)(TExtendedLocale&);
+
+// Runtime resolved functions
+static FormatFunc ptrTimeFormatL = NULL;
+static FormatSpecFunc ptrGetTimeFormatSpec = NULL;
+static FormatSpecFunc ptrGetLongDateFormatSpec = NULL;
+static FormatSpecFunc ptrGetShortDateFormatSpec = NULL;
+
+// Default functions if functions cannot be resolved
+static void defaultTimeFormatL(TTime&, TDes& des, const TDesC&, const TLocale&)
+{
+ des.Zero();
+}
+
+static TPtrC defaultFormatSpec(TExtendedLocale&)
+{
+ return TPtrC(KNullDesC);
+}
+
+/*!
+ Definition of struct for mapping Symbian to ISO locale
+*/
+struct symbianToISO {
+ int symbian_language;
+ char iso_name[8];
+};
+
+
+/*!
+ Mapping from Symbian to ISO locale
+*/
+static const symbianToISO symbian_to_iso_list[] = {
+ { ELangEnglish, "en_GB" },
+ { ELangFrench, "fr_FR" },
+ { ELangGerman, "de_DE" },
+ { ELangSpanish, "es_ES" },
+ { ELangItalian, "it_IT" },
+ { ELangSwedish, "sv_SE" },
+ { ELangDanish, "da_DK" },
+ { ELangNorwegian, "no_NO" },
+ { ELangFinnish, "fi_FI" },
+ { ELangAmerican, "en_US" },
+ { ELangPortuguese, "pt_PT" },
+ { ELangTurkish, "tr_TR" },
+ { ELangIcelandic, "is_IS" },
+ { ELangRussian, "ru_RU" },
+ { ELangHungarian, "hu_HU" },
+ { ELangDutch, "nl_NL" },
+ { ELangBelgianFlemish, "nl_BE" },
+ { ELangCzech, "cs_CZ" },
+ { ELangSlovak, "sk_SK" },
+ { ELangPolish, "pl_PL" },
+ { ELangSlovenian, "sl_SI" },
+ { ELangTaiwanChinese, "zh_TW" },
+ { ELangHongKongChinese, "zh_HK" },
+ { ELangPrcChinese, "zh_CN" },
+ { ELangJapanese, "ja_JP" },
+ { ELangThai, "th_TH" },
+ { ELangArabic, "ar_AE" },
+ { ELangTagalog, "tl_PH" },
+ { ELangBulgarian, "bg_BG" },
+ { ELangCatalan, "ca_ES" },
+ { ELangCroatian, "hr_HR" },
+ { ELangEstonian, "et_EE" },
+ { ELangFarsi, "fa_IR" },
+ { ELangCanadianFrench, "fr_CA" },
+ { ELangGreek, "el_GR" },
+ { ELangHebrew, "he_IL" },
+ { ELangHindi, "hi_IN" },
+ { ELangIndonesian, "id_ID" },
+ { ELangLatvian, "lv_LV" },
+ { ELangLithuanian, "lt_LT" },
+ { ELangMalay, "ms_MY" },
+ { ELangBrazilianPortuguese, "pt_BR" },
+ { ELangRomanian, "ro_RO" },
+ { ELangSerbian, "sr_YU" },
+ { ELangLatinAmericanSpanish, "es" },
+ { ELangUkrainian, "uk_UA" },
+ { ELangUrdu, "ur_PK" }, // India/Pakistan
+ { ELangVietnamese, "vi_VN" },
+#ifdef __E32LANG_H__
+// 5.0
+ { ELangBasque, "eu_ES" },
+ { ELangGalician, "gl_ES" },
+#endif
+#if !defined(__SERIES60_31__)
+ { ELangEnglish_Apac, "en" },
+ { ELangEnglish_Taiwan, "en_TW" },
+ { ELangEnglish_HongKong, "en_HK" },
+ { ELangEnglish_Prc, "en_CN" },
+ { ELangEnglish_Japan, "en_JP"},
+ { ELangEnglish_Thailand, "en_TH" },
+ { ELangMalay_Apac, "ms" }
+#endif
+};
+
+/*!
+ Returns ISO name corresponding to the Symbian locale code \a sys_fmt.
+*/
+static QByteArray symbianLocaleName(int code)
+{
+ //Number of Symbian to ISO locale mappings
+ static const int symbian_to_iso_count
+ = sizeof(symbian_to_iso_list)/sizeof(symbianToISO);
+
+ int cmp = code - symbian_to_iso_list[0].symbian_language;
+ if (cmp < 0)
+ return 0;
+
+ if (cmp == 0)
+ return symbian_to_iso_list[0].iso_name;
+
+ int begin = 0;
+ int end = symbian_to_iso_count;
+
+ while (end - begin > 1) {
+ uint mid = (begin + end)/2;
+
+ const symbianToISO *elt = symbian_to_iso_list + mid;
+ int cmp = code - elt->symbian_language;
+ if (cmp < 0)
+ end = mid;
+ else if (cmp > 0)
+ begin = mid;
+ else
+ return elt->iso_name;
+ }
+
+ return 0;
+}
+
+
+// order is: normal, abbr, nmode, nmode+abbr
+static const char *us_locale_dep[] = {
+ "MM", "dd", "yyyy", "MM", "dd",
+ "M", "d", "yy", "M", "d",
+ "MMMM", "dd", "yyyy", "MMMM", "dd",
+ "MMM", "d", "yy", "MMM", "d" };
+
+static const char *eu_locale_dep[] = {
+ "dd", "MM", "yyyy", "dd", "MM",
+ "d", "M", "yy", "d", "M",
+ "dd", "MMMM", "yyyy", "dd", "MMMM",
+ "d", "MMM", "yy", "d", "MMM" };
+
+static const char *jp_locale_dep[] = {
+ "yyyy", "MM", "dd", "MM", "dd",
+ "yy", "M", "d", "M", "d",
+ "yyyy", "MMMM", "dd", "MMMM", "dd",
+ "yy", "MMM", "d", "MMM", "d" };
+
+/*!
+ Returns a Qt version of the given \a sys_fmt Symbian locale format string.
+*/
+static QString s60ToQtFormat(const QString &sys_fmt)
+{
+ TLocale *locale = _s60Locale.GetLocale();
+
+ QString result;
+ QString other;
+ QString qtformatchars = QString::fromLatin1("adhmsyzAHM");
+
+ QChar c;
+ int i = 0;
+ bool open_escape = false;
+ bool abbrev_next = false;
+ bool locale_indep_ordering = false;
+ bool minus_mode = false;
+ bool plus_mode = false;
+ bool n_mode = false;
+ TTimeFormat tf = locale->TimeFormat();
+
+ while (i < sys_fmt.size()) {
+
+ c = sys_fmt.at(i);
+
+ // let formatting thru
+ if (c.unicode() == '%') {
+ // if we have gathered string, concat it
+ if (!other.isEmpty()) {
+ result += other;
+ other.clear();
+ }
+ // if we have open escape, end it
+ if (open_escape) {
+ result += QLatin1Char('\'');
+ open_escape = false;
+ }
+
+ ++i;
+ if (i >= sys_fmt.size())
+ break;
+
+ c = sys_fmt.at(i);
+
+ // process specials
+ abbrev_next = c.unicode() == '*';
+ plus_mode = c.unicode() == '+';
+ minus_mode = c.unicode() == '-';
+
+ if (abbrev_next || plus_mode || minus_mode) {
+ ++i;
+ if (i >= sys_fmt.size())
+ break;
+
+ c = sys_fmt.at(i);
+
+ if (plus_mode || minus_mode) {
+ // break on undefined plus/minus mode
+ if (c.unicode() != 'A' && c.unicode() != 'B')
+ break;
+ }
+ }
+
+ switch (c.unicode()) {
+ case 'F':
+ // locale indep mode on
+ locale_indep_ordering = true;
+ break;
+
+ case '/':
+ // date sep 0-3
+ ++i;
+ if (i >= sys_fmt.size())
+ break;
+
+ c = sys_fmt.at(i);
+ if (c.isDigit() && c.digitValue() <= 3) {
+ TChar s = locale->DateSeparator(c.digitValue());
+ TUint val = s;
+ // some indexes return zero for empty
+ if (val > 0)
+ result += QChar(val);
+ }
+ break;
+
+ case 'D':
+ if (!locale_indep_ordering)
+ break;
+
+ if (!abbrev_next)
+ result += QLatin1String("dd");
+ else
+ result += QLatin1Char('d');
+
+ break;
+
+ case 'M':
+ if (!locale_indep_ordering)
+ break;
+
+ if (!n_mode) {
+ if (!abbrev_next)
+ result += QLatin1String("MM");
+ else
+ result += QLatin1String("M");
+ } else {
+ if (!abbrev_next)
+ result += QLatin1String("MMMM");
+ else
+ result += QLatin1String("MMM");
+ }
+
+ break;
+
+ case 'N':
+ n_mode = true;
+
+ if (!locale_indep_ordering)
+ break;
+
+ if (!abbrev_next)
+ result += QLatin1String("MMMM");
+ else
+ result += QLatin1String("MMM");
+
+ break;
+
+ case 'Y':
+ if (!locale_indep_ordering)
+ break;
+
+ if (!abbrev_next)
+ result += QLatin1String("yyyy");
+ else
+ result += QLatin1String("yy");
+
+ break;
+
+ case 'E':
+ if (!abbrev_next)
+ result += QLatin1String("dddd");
+ else
+ result += QLatin1String("ddd");
+
+ break;
+
+ case ':':
+ // timesep 0-3
+ ++i;
+ if (i >= sys_fmt.size())
+ break;
+
+ c = sys_fmt.at(i);
+ if (c.isDigit() && c.digitValue() <= 3) {
+ TChar s = locale->TimeSeparator(c.digitValue());
+ TUint val = s;
+ // some indexes return zero for empty
+ if (val > 0)
+ result += QChar(val);
+ }
+
+ break;
+
+ case 'J':
+ if (tf == ETime24 && !abbrev_next)
+ result += QLatin1String("hh");
+ else
+ result += QLatin1Char('h');
+
+ break;
+
+ case 'H':
+ if (!abbrev_next)
+ result += QLatin1String("hh");
+ else
+ result += QLatin1Char('h');
+
+ break;
+
+ case 'I':
+ result += QLatin1Char('h');
+ break;
+
+ case 'T':
+ if (!abbrev_next)
+ result += QLatin1String("mm");
+ else
+ result += QLatin1Char('m');
+
+ break;
+
+ case 'S':
+ if (!abbrev_next)
+ result += QLatin1String("ss");
+ else
+ result += QLatin1Char('s');
+
+ break;
+
+ case 'B':
+ // only done for 12h clock
+ if (tf == ETime24)
+ break;
+
+ // fallthru to A
+ case 'A': {
+ // quickie to get capitalization, can't use s60 string as is because Qt 'hh' format's am/pm logic
+ TAmPmName ampm = TAmPmName();
+ TChar first(ampm[0]);
+ QString qtampm = QString::fromLatin1(first.IsUpper() ? "AP" : "ap");
+
+ int pos = locale->AmPmSymbolPosition();
+
+ if ((minus_mode && pos != ELocaleBefore) ||
+ (plus_mode && pos != ELocaleAfter))
+ break;
+
+ if (!abbrev_next && locale->AmPmSpaceBetween()) {
+ if (pos == ELocaleBefore)
+ qtampm.append(QLatin1Char(' '));
+ else
+ qtampm.prepend(QLatin1Char(' '));
+ }
+
+ result += qtampm;
+ }
+ break;
+
+ case '.': {
+ // decimal sep
+ TChar s = locale->DecimalSeparator();
+ TUint val = s;
+ if (val > 0)
+ result += QChar(val);
+ }
+ break;
+
+ case 'C':
+ // six digits in s60, three digits in qt
+ if (!abbrev_next) {
+ result += QLatin1String("zzz");
+ } else {
+ // next char is number from 0-6, how many digits to display
+ ++i;
+ if (i >= sys_fmt.size())
+ break;
+
+ c = sys_fmt.at(i);
+
+ if (c.isDigit()) {
+ // try to match wanted digits
+ QChar val(c.digitValue());
+
+ if (val >= 3) {
+ result += QLatin1String("zzz");
+ } else if (val > 0) {
+ result += QLatin1Char('z');
+ }
+ }
+ }
+ break;
+
+ // these cases fallthru
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+
+ // shouldn't parse these with %F
+ if (locale_indep_ordering)
+ break;
+
+ TDateFormat df = locale->DateFormat();
+
+ const char **locale_dep;
+ switch (df) {
+ default: // fallthru to american
+ case EDateAmerican:
+ locale_dep = us_locale_dep;
+ break;
+ case EDateEuropean:
+ locale_dep = eu_locale_dep;
+ break;
+ case EDateJapanese:
+ locale_dep = jp_locale_dep;
+ break;
+ }
+ int offset = 0;
+ if (abbrev_next)
+ offset += 5;
+ if (n_mode)
+ offset += 10;
+
+ result += QLatin1String(locale_dep[offset + (c.digitValue()-1)]);
+ break;
+
+ case '%': // fallthru percent
+ // any junk gets copied as is
+ default:
+ result += c;
+ break;
+
+ case 'Z': // Qt doesn't support these :(
+ case 'X':
+ case 'W':
+ break;
+ }
+ } else {
+ // double any single quotes, don't begin escape
+ if (c.unicode() == '\'') {
+ // end open escape
+ if (open_escape) {
+ result += other;
+ other.clear();
+ result += QLatin1Char('\'');
+ open_escape = false;
+ }
+
+ other += c;
+ }
+
+ // gather chars and escape them in one go if any format chars are found
+ if (!open_escape && qtformatchars.indexOf(c) != -1) {
+ result += QLatin1Char('\'');
+ open_escape = true;
+ }
+ other += c;
+ }
+
+ ++i;
+ }
+
+ if (!other.isEmpty())
+ result += other;
+ if (open_escape)
+ result += QLatin1Char('\'');
+
+ return result;
+}
+
+/*!
+ Retrieves Symbian locale decimal separator.
+*/
+static QString symbianDecimalPoint()
+{
+ TLocale *locale = _s60Locale.GetLocale();
+
+ TChar decPoint = locale->DecimalSeparator();
+ int val = decPoint;
+ return QChar(val);
+}
+
+/*!
+ Retrieves Symbian locale group separator.
+*/
+static QString symbianGroupSeparator()
+{
+ TLocale *locale = _s60Locale.GetLocale();
+
+ TChar grpSep = locale->ThousandsSeparator();
+ int val = grpSep;
+ return QChar(val);
+}
+
+/*!
+ Retrieves Symbian locale zero digit.
+*/
+static QString symbianZeroDigit()
+{
+ TLocale *locale = _s60Locale.GetLocale();
+
+ // TDigitType enumeration value returned by TLocale
+ // will always correspond to zero digit unicode value.
+ TDigitType digit = locale->DigitType();
+ return QChar(digit);
+}
+
+/*!
+ Retrieves a day name from Symbian locale. The \a day is an integer
+ from 1 to 7. When \a short_format is true the method returns
+ the day in short format. Otherwise it returns the day in a long format.
+*/
+static QString symbianDayName(int day, bool short_format)
+{
+ day -= 1;
+
+ if (day < 0 || day > 6)
+ return QString();
+
+ if (short_format) {
+ return qt_TDes2QStringL(TDayNameAbb(TDay(day)));
+ } else {
+ return qt_TDes2QStringL(TDayName(TDay(day)));
+ }
+}
+
+/*!
+ Retrieves a month name from Symbian locale. The \a month is an integer
+ from 1 to 12. When \a short_format is true the method returns
+ the month in short format. Otherwise it returns the month in a long format.
+*/
+static QString symbianMonthName(int month, bool short_format)
+{
+ month -= 1;
+ if (month < 0 || month > 11)
+ return QString();
+
+ if (short_format) {
+ return qt_TDes2QStringL(TMonthNameAbb(TMonth(month)));
+ } else {
+ return qt_TDes2QStringL(TMonthName(TMonth(month)));
+ }
+}
+
+/*!
+ Retrieves date format from Symbian locale and
+ transforms it to Qt format.
+
+ When \a short_format is true the method returns
+ short date format. Otherwise it returns the long format.
+*/
+static QString symbianDateFormat(bool short_format)
+{
+ TPtrC dateFormat;
+
+ if (short_format) {
+ dateFormat.Set(ptrGetShortDateFormatSpec(_s60Locale));
+ } else {
+ dateFormat.Set(ptrGetLongDateFormatSpec(_s60Locale));
+ }
+
+ return s60ToQtFormat(qt_TDesC2QStringL(dateFormat));
+}
+
+/*!
+ Retrieves time format from Symbian locale and
+ transforms it to Qt format.
+*/
+static QString symbianTimeFormat()
+{
+ return s60ToQtFormat(qt_TDesC2QStringL(ptrGetTimeFormatSpec(_s60Locale)));
+}
+
+/*!
+ Returns localized string representation of given \a date
+ formatted with Symbian locale date format.
+
+ If \a short_format is true the format will be a short version.
+ Otherwise it uses a longer version.
+*/
+static QString symbianDateToString(const QDate &date, bool short_format)
+{
+ int month = date.month() - 1;
+ int day = date.day() - 1;
+ int year = date.year();
+
+ TDateTime dateTime;
+ dateTime.Set(year, TMonth(month), day, 0, 0, 0, 0);
+
+ TTime timeStr(dateTime);
+ TBuf<KMaxLongDateFormatSpec*2> buffer;
+
+ TPtrC dateFormat;
+ if (short_format) {
+ dateFormat.Set(ptrGetShortDateFormatSpec(_s60Locale));
+ } else {
+ dateFormat.Set(ptrGetLongDateFormatSpec(_s60Locale));
+ }
+
+ TRAPD(err, ptrTimeFormatL(timeStr, buffer, dateFormat, *_s60Locale.GetLocale());)
+
+ if (err == KErrNone)
+ return qt_TDes2QStringL(buffer);
+ else
+ return QString();
+}
+
+/*!
+ Returns localized string representation of given \a time
+ formatted with Symbian locale time format.
+*/
+static QString symbianTimeToString(const QTime &time)
+{
+ int hour = time.hour();
+ int minute = time.minute();
+ int second = time.second();
+ int milliseconds = 0;
+
+ TDateTime dateTime;
+ dateTime.Set(0, TMonth(0), 0, hour, minute, second, milliseconds);
+
+ TTime timeStr(dateTime);
+ TBuf<KMaxTimeFormatSpec*2> buffer;
+
+ TRAPD(err, ptrTimeFormatL(
+ timeStr,
+ buffer,
+ ptrGetTimeFormatSpec(_s60Locale),
+ *_s60Locale.GetLocale());
+ )
+
+ if (err == KErrNone)
+ return qt_TDes2QStringL(buffer);
+ else
+ return QString();
+}
+
+/*!
+ Returns the measurement system stored in Symbian locale
+
+ \sa QLocale::MeasurementSystem
+*/
+static QLocale::MeasurementSystem symbianMeasurementSystem()
+{
+ TLocale *locale = _s60Locale.GetLocale();
+
+ TUnitsFormat unitFormat = locale->UnitsGeneral();
+ if (unitFormat == EUnitsImperial)
+ return QLocale::ImperialSystem;
+ else
+ return QLocale::MetricSystem;
+}
+
+QLocale QSystemLocale::fallbackLocale() const
+{
+ // load system data before query calls
+ static bool initDone = false;
+ if (!initDone) {
+ _s60Locale.LoadSystemSettings();
+
+ // Initialize platform version dependent function pointers
+ ptrTimeFormatL = reinterpret_cast<FormatFunc>
+ (qt_resolveS60PluginFunc(S60Plugin_TimeFormatL));
+ ptrGetTimeFormatSpec = reinterpret_cast<FormatSpecFunc>
+ (qt_resolveS60PluginFunc(S60Plugin_GetTimeFormatSpec));
+ ptrGetLongDateFormatSpec = reinterpret_cast<FormatSpecFunc>
+ (qt_resolveS60PluginFunc(S60Plugin_GetLongDateFormatSpec));
+ ptrGetShortDateFormatSpec = reinterpret_cast<FormatSpecFunc>
+ (qt_resolveS60PluginFunc(S60Plugin_GetShortDateFormatSpec));
+ if (!ptrTimeFormatL)
+ ptrTimeFormatL = &defaultTimeFormatL;
+ if (!ptrGetTimeFormatSpec)
+ ptrGetTimeFormatSpec = &defaultFormatSpec;
+ if (!ptrGetLongDateFormatSpec)
+ ptrGetLongDateFormatSpec = &defaultFormatSpec;
+ if (!ptrGetShortDateFormatSpec)
+ ptrGetShortDateFormatSpec = &defaultFormatSpec;
+ }
+
+ TLanguage lang = User::Language();
+ QString locale = symbianLocaleName(lang);
+ return QLocale(locale);
+}
+
+/*!
+ Generic query method for locale data. Provides indirection.
+ Denotes the \a type of the query
+ with \a in as input data depending on the query.
+
+ \sa QSystemLocale::QueryType
+*/
+QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
+{
+ switch(type) {
+ case DecimalPoint:
+ return symbianDecimalPoint();
+ case GroupSeparator:
+ return symbianGroupSeparator();
+
+ case ZeroDigit:
+ return symbianZeroDigit();
+
+ case DayNameLong:
+ case DayNameShort:
+ return symbianDayName(in.toInt(), (type == DayNameShort) );
+
+ case MonthNameLong:
+ case MonthNameShort:
+ return symbianMonthName(in.toInt(), (type == MonthNameShort) );
+
+ case DateFormatLong:
+ case DateFormatShort:
+ return symbianDateFormat( (type == DateFormatShort) );
+ case TimeFormatLong:
+ case TimeFormatShort:
+ return symbianTimeFormat();
+ case DateTimeFormatLong:
+ case DateTimeFormatShort:
+ return symbianDateFormat( (type == DateTimeFormatShort) ) + QLatin1Char(' ') + symbianTimeFormat();
+ case DateToStringShort:
+ case DateToStringLong:
+ return symbianDateToString(in.toDate(), (type == DateToStringShort) );
+ case TimeToStringShort:
+ case TimeToStringLong:
+ return symbianTimeToString(in.toTime());
+ case DateTimeToStringShort:
+ case DateTimeToStringLong: {
+ const QDateTime dt = in.toDateTime();
+ return symbianDateToString(dt.date(), (type == DateTimeToStringShort) )
+ + QLatin1Char(' ') + symbianTimeToString(dt.time());
+ }
+ case MeasurementSystem:
+ return static_cast<int>(symbianMeasurementSystem());
+ case LanguageId:
+ case CountryId: {
+ TLanguage language = User::Language();
+ QString locale = symbianLocaleName(language);
+ QLocale::Language lang;
+ QLocale::Country cntry;
+ getLangAndCountry(locale, lang, cntry);
+ if (type == LanguageId)
+ return lang;
+ // few iso codes have no country and will use this
+ if (cntry == QLocale::AnyCountry)
+ return fallbackLocale().country();
+
+ return cntry;
+ }
+ case NegativeSign:
+ case PositiveSign:
+ case AMText:
+ case PMText:
+ break;
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 45e92bf..c2381ce 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -65,6 +65,7 @@ SOURCES += \
tools/qvector.cpp \
tools/qvsnprintf.cpp
+symbian:SOURCES+=tools/qlocale_symbian.cpp
#zlib support
contains(QT_CONFIG, zlib) {