Use QCollator in QString and remove it from qlocale_icu
[profile/ivi/qtbase.git] / src / corelib / tools / qlocale_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QLOCALE_P_H
43 #define QLOCALE_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists for the convenience
50 // of internal files.  This header file may change from version to version
51 // without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "QtCore/qstring.h"
57 #include "QtCore/qvarlengtharray.h"
58 #include "QtCore/qvariant.h"
59
60 #include "qlocale.h"
61
62 QT_BEGIN_NAMESPACE
63
64 #ifndef QT_NO_SYSTEMLOCALE
65 class QSystemLocale
66 {
67 public:
68     QSystemLocale();
69     virtual ~QSystemLocale();
70
71     struct CurrencyToStringArgument
72     {
73         CurrencyToStringArgument() { }
74         CurrencyToStringArgument(const QVariant &v, const QString &s)
75             : value(v), symbol(s) { }
76         QVariant value;
77         QString symbol;
78     };
79
80     enum QueryType {
81         LanguageId, // uint
82         CountryId, // uint
83         DecimalPoint, // QString
84         GroupSeparator, // QString
85         ZeroDigit, // QString
86         NegativeSign, // QString
87         DateFormatLong, // QString
88         DateFormatShort, // QString
89         TimeFormatLong, // QString
90         TimeFormatShort, // QString
91         DayNameLong, // QString, in: int
92         DayNameShort, // QString, in: int
93         MonthNameLong, // QString, in: int
94         MonthNameShort, // QString, in: int
95         DateToStringLong, // QString, in: QDate
96         DateToStringShort, // QString in: QDate
97         TimeToStringLong, // QString in: QTime
98         TimeToStringShort, // QString in: QTime
99         DateTimeFormatLong, // QString
100         DateTimeFormatShort, // QString
101         DateTimeToStringLong, // QString in: QDateTime
102         DateTimeToStringShort, // QString in: QDateTime
103         MeasurementSystem, // uint
104         PositiveSign, // QString
105         AMText, // QString
106         PMText, // QString
107         FirstDayOfWeek, // Qt::DayOfWeek
108         Weekdays, // QList<Qt::DayOfWeek>
109         CurrencySymbol, // QString in: CurrencyToStringArgument
110         CurrencyToString, // QString in: qlonglong, qulonglong or double
111         UILanguages, // QStringList
112         StringToStandardQuotation, // QString in: QStringRef to quote
113         StringToAlternateQuotation, // QString in: QStringRef to quote
114         ScriptId, // uint
115         ListToSeparatedString, // QString
116         LocaleChanged, // system locale changed
117         NativeLanguageName, // QString
118         NativeCountryName // QString
119     };
120     virtual QVariant query(QueryType type, QVariant in) const;
121     virtual QLocale fallbackUiLocale() const;
122
123 private:
124     QSystemLocale(bool);
125     friend class QSystemLocaleSingleton;
126 };
127 #endif
128
129 #ifdef QT_USE_ICU
130 namespace QIcu {
131     QString toUpper(const QByteArray &localeId, const QString &str, bool *ok);
132     QString toLower(const QByteArray &localeId, const QString &str, bool *ok);
133 }
134 #endif
135
136
137 struct QLocaleData
138 {
139 public:
140     static const QLocaleData *findLocaleData(QLocale::Language language,
141                                              QLocale::Script script,
142                                              QLocale::Country country);
143
144     quint16 m_language_id, m_script_id, m_country_id;
145
146     quint16 m_decimal, m_group, m_list, m_percent, m_zero, m_minus, m_plus, m_exponential;
147     quint16 m_quotation_start, m_quotation_end;
148     quint16 m_alternate_quotation_start, m_alternate_quotation_end;
149
150     quint16 m_list_pattern_part_start_idx, m_list_pattern_part_start_size;
151     quint16 m_list_pattern_part_mid_idx, m_list_pattern_part_mid_size;
152     quint16 m_list_pattern_part_end_idx, m_list_pattern_part_end_size;
153     quint16 m_list_pattern_part_two_idx, m_list_pattern_part_two_size;
154     quint16 m_short_date_format_idx, m_short_date_format_size;
155     quint16 m_long_date_format_idx, m_long_date_format_size;
156     quint16 m_short_time_format_idx, m_short_time_format_size;
157     quint16 m_long_time_format_idx, m_long_time_format_size;
158     quint16 m_standalone_short_month_names_idx, m_standalone_short_month_names_size;
159     quint16 m_standalone_long_month_names_idx, m_standalone_long_month_names_size;
160     quint16 m_standalone_narrow_month_names_idx, m_standalone_narrow_month_names_size;
161     quint16 m_short_month_names_idx, m_short_month_names_size;
162     quint16 m_long_month_names_idx, m_long_month_names_size;
163     quint16 m_narrow_month_names_idx, m_narrow_month_names_size;
164     quint16 m_standalone_short_day_names_idx, m_standalone_short_day_names_size;
165     quint16 m_standalone_long_day_names_idx, m_standalone_long_day_names_size;
166     quint16 m_standalone_narrow_day_names_idx, m_standalone_narrow_day_names_size;
167     quint16 m_short_day_names_idx, m_short_day_names_size;
168     quint16 m_long_day_names_idx, m_long_day_names_size;
169     quint16 m_narrow_day_names_idx, m_narrow_day_names_size;
170     quint16 m_am_idx, m_am_size;
171     quint16 m_pm_idx, m_pm_size;
172     char    m_currency_iso_code[3];
173     quint16 m_currency_symbol_idx, m_currency_symbol_size;
174     quint16 m_currency_display_name_idx, m_currency_display_name_size;
175     quint8  m_currency_format_idx, m_currency_format_size;
176     quint8  m_currency_negative_format_idx, m_currency_negative_format_size;
177     quint16 m_language_endonym_idx, m_language_endonym_size;
178     quint16 m_country_endonym_idx, m_country_endonym_size;
179     quint16 m_currency_digits : 2;
180     quint16 m_currency_rounding : 3;
181     quint16 m_first_day_of_week : 3;
182     quint16 m_weekend_start : 3;
183     quint16 m_weekend_end : 3;
184 };
185
186 class Q_CORE_EXPORT QLocalePrivate : public QSharedData
187 {
188 public:
189     QLocalePrivate(int index, int numberOptions = 0)
190         : m_index(index), m_numberOptions(numberOptions)
191     {
192         m_data = dataPointerForIndex(index);
193         m_localeID = bcp47Name().toLatin1();
194         m_localeID.replace('-','_');
195     }
196
197     ~QLocalePrivate()
198     {
199     }
200
201     QChar decimal() const { return QChar(m_data->m_decimal); }
202     QChar group() const { return QChar(m_data->m_group); }
203     QChar list() const { return QChar(m_data->m_list); }
204     QChar percent() const { return QChar(m_data->m_percent); }
205     QChar zero() const { return QChar(m_data->m_zero); }
206     QChar plus() const { return QChar(m_data->m_plus); }
207     QChar minus() const { return QChar(m_data->m_minus); }
208     QChar exponential() const { return QChar(m_data->m_exponential); }
209
210     quint16 languageId() const { return m_data->m_language_id; }
211     quint16 countryId() const { return m_data->m_country_id; }
212
213     QString bcp47Name() const;
214
215     QString languageCode() const; // ### QByteArray::fromRawData would be more optimal
216     QString scriptCode() const;
217     QString countryCode() const;
218
219     static QLocale::Language codeToLanguage(const QString &code);
220     static QLocale::Script codeToScript(const QString &code);
221     static QLocale::Country codeToCountry(const QString &code);
222     static void getLangAndCountry(const QString &name, QLocale::Language &lang,
223                                   QLocale::Script &script, QLocale::Country &cntry);
224     static const QLocaleData *dataPointerForIndex(quint16 index);
225
226     QLocale::MeasurementSystem measurementSystem() const;
227
228     enum DoubleForm {
229         DFExponent = 0,
230         DFDecimal,
231         DFSignificantDigits,
232         _DFMax = DFSignificantDigits
233     };
234
235     enum Flags {
236         NoFlags             = 0,
237         Alternate           = 0x01,
238         ZeroPadded          = 0x02,
239         LeftAdjusted        = 0x04,
240         BlankBeforePositive = 0x08,
241         AlwaysShowSign      = 0x10,
242         ThousandsGroup      = 0x20,
243         CapitalEorX         = 0x40,
244
245         ShowBase            = 0x80,
246         UppercaseBase       = 0x100,
247         ForcePoint          = Alternate
248     };
249
250     enum GroupSeparatorMode {
251         FailOnGroupSeparators,
252         ParseGroupSeparators
253     };
254
255     static QString doubleToString(const QChar zero, const QChar plus,
256                                   const QChar minus, const QChar exponent,
257                                   const QChar group, const QChar decimal,
258                                   double d, int precision,
259                                   DoubleForm form,
260                                   int width, unsigned flags);
261     static QString longLongToString(const QChar zero, const QChar group,
262                                     const QChar plus, const QChar minus,
263                                     qint64 l, int precision, int base,
264                                     int width, unsigned flags);
265     static QString unsLongLongToString(const QChar zero, const QChar group,
266                                        const QChar plus,
267                                        quint64 l, int precision,
268                                        int base, int width,
269                                        unsigned flags);
270
271     QString doubleToString(double d,
272                            int precision = -1,
273                            DoubleForm form = DFSignificantDigits,
274                            int width = -1,
275                            unsigned flags = NoFlags) const;
276     QString longLongToString(qint64 l, int precision = -1,
277                              int base = 10,
278                              int width = -1,
279                              unsigned flags = NoFlags) const;
280     QString unsLongLongToString(quint64 l, int precision = -1,
281                                 int base = 10,
282                                 int width = -1,
283                                 unsigned flags = NoFlags) const;
284     double stringToDouble(const QString &num, bool *ok, GroupSeparatorMode group_sep_mode) const;
285     qint64 stringToLongLong(const QString &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
286     quint64 stringToUnsLongLong(const QString &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
287
288
289     static double bytearrayToDouble(const char *num, bool *ok, bool *overflow = 0);
290     static qint64 bytearrayToLongLong(const char *num, int base, bool *ok, bool *overflow = 0);
291     static quint64 bytearrayToUnsLongLong(const char *num, int base, bool *ok);
292
293     typedef QVarLengthArray<char, 256> CharBuff;
294     bool numberToCLocale(const QString &num,
295                           GroupSeparatorMode group_sep_mode,
296                           CharBuff *result) const;
297     inline char digitToCLocale(QChar c) const;
298
299     static void updateSystemPrivate();
300
301     enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode };
302     bool validateChars(const QString &str, NumberMode numMode, QByteArray *buff, int decDigits = -1) const;
303
304     QString dateTimeToString(const QString &format, const QDate *date, const QTime *time,
305                              const QLocale *q) const;
306
307     friend class QLocale;
308     quint16 m_index;
309     quint16 m_numberOptions;
310     const QLocaleData *m_data;
311     QByteArray m_localeID;
312 };
313
314 inline char QLocalePrivate::digitToCLocale(QChar in) const
315 {
316     const QChar _zero = zero();
317     const QChar _group = group();
318     const ushort zeroUnicode = _zero.unicode();
319     const ushort tenUnicode = zeroUnicode + 10;
320
321     if (in.unicode() >= zeroUnicode && in.unicode() < tenUnicode)
322         return '0' + in.unicode() - zeroUnicode;
323
324     if (in.unicode() >= '0' && in.unicode() <= '9')
325         return in.toLatin1();
326
327     if (in == plus())
328         return '+';
329
330     if (in == minus())
331         return '-';
332
333     if (in == decimal())
334         return '.';
335
336     if (in == group())
337         return ',';
338
339     if (in == exponential() || in == exponential().toUpper())
340         return 'e';
341
342     // In several languages group() is the char 0xA0, which looks like a space.
343     // People use a regular space instead of it and complain it doesn't work.
344     if (_group.unicode() == 0xA0 && in.unicode() == ' ')
345         return ',';
346
347     return 0;
348 }
349
350 QString qt_readEscapedFormatString(const QString &format, int *idx);
351 bool qt_splitLocaleName(const QString &name, QString &lang, QString &script, QString &cntry);
352 int qt_repeatCount(const QString &s, int i);
353
354 QT_END_NAMESPACE
355
356 Q_DECLARE_METATYPE(QStringRef)
357 Q_DECLARE_METATYPE(QList<Qt::DayOfWeek>)
358 #ifndef QT_NO_SYSTEMLOCALE
359 Q_DECLARE_METATYPE(QSystemLocale::CurrencyToStringArgument)
360 #endif
361
362 #endif // QLOCALE_P_H