1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
42 #include "qqmllocale_p.h"
43 #include "qqmlengine_p.h"
44 #include <private/qqmlcontext_p.h>
45 #include <private/qjsconverter_impl_p.h>
46 #include <QtCore/qnumeric.h>
47 #include <QtCore/qdatetime.h>
49 #include <private/qlocale_p.h>
50 #include <private/qlocale_data_p.h>
54 class QV8LocaleDataResource : public QV8ObjectResource
56 V8_RESOURCE_TYPE(LocaleDataType)
58 QV8LocaleDataResource(QV8Engine *e) : QV8ObjectResource(e) {}
62 #define GET_LOCALE_DATA_RESOURCE(OBJECT) \
63 QV8LocaleDataResource *r = v8_resource_cast<QV8LocaleDataResource>(OBJECT); \
65 V8THROW_ERROR("Not a valid Locale object")
67 static bool isLocaleObject(v8::Handle<v8::Value> val)
72 v8::Handle<v8::Object> localeObj = val->ToObject();
73 return localeObj->Has(v8::String::New("nativeLanguageName")); //XXX detect locale object properly
79 static const char *dateToLocaleStringFunction =
80 "(function(toLocaleStringFunc) { "
81 " var orig_toLocaleString;"
82 " orig_toLocaleString = Date.prototype.toLocaleString;"
83 " Date.prototype.toLocaleString = (function() {"
84 " var val = toLocaleStringFunc.apply(this, arguments);"
85 " if (val == undefined) val = orig_toLocaleString.call(this);"
90 static const char *dateToLocaleTimeStringFunction =
91 "(function(toLocaleTimeStringFunc) { "
92 " var orig_toLocaleTimeString;"
93 " orig_toLocaleTimeString = Date.prototype.toLocaleTimeString;"
94 " Date.prototype.toLocaleTimeString = (function() {"
95 " var val = toLocaleTimeStringFunc.apply(this, arguments);"
96 " if (val == undefined) val = orig_toLocaleTimeString.call(this);"
101 static const char *dateToLocaleDateStringFunction =
102 "(function(toLocaleDateStringFunc) { "
103 " var orig_toLocaleDateString;"
104 " orig_toLocaleDateString = Date.prototype.toLocaleDateString;"
105 " Date.prototype.toLocaleDateString = (function() {"
106 " var val = toLocaleDateStringFunc.apply(this, arguments);"
107 " if (val == undefined) val = orig_toLocaleDateString.call(this);"
113 static const char *dateFromLocaleStringFunction =
114 "(function(fromLocaleStringFunc) { "
115 " Date.fromLocaleString = (function() {"
116 " return fromLocaleStringFunc.apply(null, arguments);"
120 static const char *dateFromLocaleTimeStringFunction =
121 "(function(fromLocaleTimeStringFunc) { "
122 " Date.fromLocaleTimeString = (function() {"
123 " return fromLocaleTimeStringFunc.apply(null, arguments);"
127 static const char *dateFromLocaleDateStringFunction =
128 "(function(fromLocaleDateStringFunc) { "
129 " Date.fromLocaleDateString = (function() {"
130 " return fromLocaleDateStringFunc.apply(null, arguments);"
135 static void registerFunction(QV8Engine *engine, const char *script, v8::InvocationCallback func)
137 v8::Local<v8::Script> registerScript = v8::Script::New(v8::String::New(script), 0, 0, v8::Handle<v8::String>(), v8::Script::NativeMode);
138 v8::Local<v8::Value> result = registerScript->Run();
139 Q_ASSERT(result->IsFunction());
140 v8::Local<v8::Function> registerFunc = v8::Local<v8::Function>::Cast(result);
141 v8::Handle<v8::Value> args = V8FUNCTION(func, engine);
142 registerFunc->Call(v8::Local<v8::Object>::Cast(registerFunc), 1, &args);
145 void QQmlDateExtension::registerExtension(QV8Engine *engine)
147 registerFunction(engine, dateToLocaleStringFunction, toLocaleString);
148 registerFunction(engine, dateToLocaleTimeStringFunction, toLocaleTimeString);
149 registerFunction(engine, dateToLocaleDateStringFunction, toLocaleDateString);
150 registerFunction(engine, dateFromLocaleStringFunction, fromLocaleString);
151 registerFunction(engine, dateFromLocaleTimeStringFunction, fromLocaleTimeString);
152 registerFunction(engine, dateFromLocaleDateStringFunction, fromLocaleDateString);
155 v8::Handle<v8::Value> QQmlDateExtension::toLocaleString(const v8::Arguments& args)
157 if (args.Length() > 2)
158 return v8::Undefined();
160 if (!args.This()->IsDate())
161 return v8::Undefined();
163 QDateTime dt = QV8Engine::qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(args.This())->NumberValue());
165 if (args.Length() == 0) {
166 // Use QLocale for standard toLocaleString() function
168 return QJSConverter::toString(locale.toString(dt));
171 if (!isLocaleObject(args[0]))
172 return v8::Undefined(); // Use the default Date toLocaleString()
174 GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
176 QLocale::FormatType enumFormat = QLocale::LongFormat;
178 if (args.Length() == 2) {
179 if (args[1]->IsString()) {
180 QString format = r->engine->toVariant(args[1], -1).toString();
181 formattedDt = r->locale.toString(dt, format);
182 } else if (args[1]->IsNumber()) {
183 quint32 intFormat = args[1]->ToNumber()->Value();
184 QLocale::FormatType format = QLocale::FormatType(intFormat);
185 formattedDt = r->locale.toString(dt, format);
187 V8THROW_ERROR("Locale: Date.toLocaleString(): Invalid datetime format");
190 formattedDt = r->locale.toString(dt, enumFormat);
193 return r->engine->toString(formattedDt);
196 v8::Handle<v8::Value> QQmlDateExtension::toLocaleTimeString(const v8::Arguments& args)
198 if (args.Length() > 2)
199 return v8::Undefined();
201 if (!args.This()->IsDate())
202 return v8::Undefined();
204 QDateTime dt = QV8Engine::qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(args.This())->NumberValue());
205 QTime time = dt.time();
207 if (args.Length() == 0) {
208 // Use QLocale for standard toLocaleString() function
210 return QJSConverter::toString(locale.toString(time));
213 if (!isLocaleObject(args[0]))
214 return v8::Undefined(); // Use the default Date toLocaleTimeString()
216 GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
218 QLocale::FormatType enumFormat = QLocale::LongFormat;
219 QString formattedTime;
220 if (args.Length() == 2) {
221 if (args[1]->IsString()) {
222 QString format = r->engine->toVariant(args[1], -1).toString();
223 formattedTime = r->locale.toString(time, format);
224 } else if (args[1]->IsNumber()) {
225 quint32 intFormat = args[1]->ToNumber()->Value();
226 QLocale::FormatType format = QLocale::FormatType(intFormat);
227 formattedTime = r->locale.toString(time, format);
229 V8THROW_ERROR("Locale: Date.toLocaleTimeString(): Invalid time format");
232 formattedTime = r->locale.toString(time, enumFormat);
235 return r->engine->toString(formattedTime);
238 v8::Handle<v8::Value> QQmlDateExtension::toLocaleDateString(const v8::Arguments& args)
240 if (args.Length() > 2)
241 return v8::Undefined();
243 if (!args.This()->IsDate())
244 return v8::Undefined();
246 QDateTime dt = QV8Engine::qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(args.This())->NumberValue());
247 QDate date = dt.date();
249 if (args.Length() == 0) {
250 // Use QLocale for standard toLocaleString() function
252 return QJSConverter::toString(locale.toString(date));
255 if (!isLocaleObject(args[0]))
256 return v8::Undefined(); // Use the default Date toLocaleDateString()
258 GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
260 QLocale::FormatType enumFormat = QLocale::LongFormat;
261 QString formattedDate;
262 if (args.Length() == 2) {
263 if (args[1]->IsString()) {
264 QString format = r->engine->toVariant(args[1], -1).toString();
265 formattedDate = r->locale.toString(date, format);
266 } else if (args[1]->IsNumber()) {
267 quint32 intFormat = args[1]->ToNumber()->Value();
268 QLocale::FormatType format = QLocale::FormatType(intFormat);
269 formattedDate = r->locale.toString(date, format);
271 V8THROW_ERROR("Locale: Date.loLocaleDateString(): Invalid date format");
274 formattedDate = r->locale.toString(date, enumFormat);
277 return r->engine->toString(formattedDate);
280 v8::Handle<v8::Value> QQmlDateExtension::fromLocaleString(const v8::Arguments& args)
282 if (args.Length() == 1 && args[0]->IsString()) {
284 QString dateString = QJSConverter::toString(args[0]->ToString());
285 QDateTime dt = locale.toDateTime(dateString);
286 return QJSConverter::toDateTime(dt);
289 if (args.Length() < 1 || args.Length() > 3 || !isLocaleObject(args[0]))
290 V8THROW_ERROR("Locale: Date.fromLocaleString(): Invalid arguments");
292 GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
294 QLocale::FormatType enumFormat = QLocale::LongFormat;
296 QString dateString = r->engine->toString(args[1]->ToString());
297 if (args.Length() == 3) {
298 if (args[2]->IsString()) {
299 QString format = r->engine->toString(args[2]->ToString());
300 dt = r->locale.toDateTime(dateString, format);
301 } else if (args[2]->IsNumber()) {
302 quint32 intFormat = args[2]->ToNumber()->Value();
303 QLocale::FormatType format = QLocale::FormatType(intFormat);
304 dt = r->locale.toDateTime(dateString, format);
306 V8THROW_ERROR("Locale: Date.fromLocaleString(): Invalid datetime format");
309 dt = r->locale.toDateTime(dateString, enumFormat);
312 return QJSConverter::toDateTime(dt);
315 v8::Handle<v8::Value> QQmlDateExtension::fromLocaleTimeString(const v8::Arguments& args)
317 if (args.Length() == 1 && args[0]->IsString()) {
319 QString timeString = QJSConverter::toString(args[0]->ToString());
320 QTime time = locale.toTime(timeString);
321 QDateTime dt = QDateTime::currentDateTime();
323 return QJSConverter::toDateTime(dt);
326 if (args.Length() < 1 || args.Length() > 3 || !isLocaleObject(args[0]))
327 V8THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid arguments");
329 GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
331 QLocale::FormatType enumFormat = QLocale::LongFormat;
333 QString dateString = r->engine->toString(args[1]->ToString());
334 if (args.Length() == 3) {
335 if (args[2]->IsString()) {
336 QString format = r->engine->toString(args[2]->ToString());
337 tm = r->locale.toTime(dateString, format);
338 } else if (args[2]->IsNumber()) {
339 quint32 intFormat = args[2]->ToNumber()->Value();
340 QLocale::FormatType format = QLocale::FormatType(intFormat);
341 tm = r->locale.toTime(dateString, format);
343 V8THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid datetime format");
346 tm = r->locale.toTime(dateString, enumFormat);
349 QDateTime dt = QDateTime::currentDateTime();
352 return QJSConverter::toDateTime(dt);
355 v8::Handle<v8::Value> QQmlDateExtension::fromLocaleDateString(const v8::Arguments& args)
357 if (args.Length() == 1 && args[0]->IsString()) {
359 QString dateString = QJSConverter::toString(args[0]->ToString());
360 QDate date = locale.toDate(dateString);
361 return QJSConverter::toDateTime(QDateTime(date));
364 if (args.Length() < 1 || args.Length() > 3 || !isLocaleObject(args[0]))
365 V8THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid arguments");
367 GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
369 QLocale::FormatType enumFormat = QLocale::LongFormat;
371 QString dateString = r->engine->toString(args[1]->ToString());
372 if (args.Length() == 3) {
373 if (args[2]->IsString()) {
374 QString format = r->engine->toString(args[2]->ToString());
375 dt = r->locale.toDate(dateString, format);
376 } else if (args[2]->IsNumber()) {
377 quint32 intFormat = args[2]->ToNumber()->Value();
378 QLocale::FormatType format = QLocale::FormatType(intFormat);
379 dt = r->locale.toDate(dateString, format);
381 V8THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid datetime format");
384 dt = r->locale.toDate(dateString, enumFormat);
387 return QJSConverter::toDateTime(QDateTime(dt));
393 static const char *numberToLocaleStringFunction =
394 "(function(toLocaleStringFunc) { "
395 " var orig_toLocaleString;"
396 " orig_toLocaleString = Number.prototype.toLocaleString;"
397 " Number.prototype.toLocaleString = (function() {"
398 " var val = toLocaleStringFunc.apply(this, arguments);"
399 " if (val == undefined) val = orig_toLocaleString.call(this);"
404 static const char *numberToLocaleCurrencyStringFunction =
405 "(function(toLocaleCurrencyStringFunc) { "
406 " Number.prototype.toLocaleCurrencyString = (function() {"
407 " return toLocaleCurrencyStringFunc.apply(this, arguments);"
411 static const char *numberFromLocaleStringFunction =
412 "(function(fromLocaleStringFunc) { "
413 " Number.fromLocaleString = (function() {"
414 " return fromLocaleStringFunc.apply(null, arguments);"
419 void QQmlNumberExtension::registerExtension(QV8Engine *engine)
421 registerFunction(engine, numberToLocaleStringFunction, toLocaleString);
422 registerFunction(engine, numberToLocaleCurrencyStringFunction, toLocaleCurrencyString);
423 registerFunction(engine, numberFromLocaleStringFunction, fromLocaleString);
426 v8::Handle<v8::Value> QQmlNumberExtension::toLocaleString(const v8::Arguments& args)
428 if (args.Length() > 3)
429 V8THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
431 double number = args.This()->ToNumber()->Value();
433 if (args.Length() == 0) {
434 // Use QLocale for standard toLocaleString() function
436 return QJSConverter::toString(locale.toString(number));
439 if (!isLocaleObject(args[0]))
440 return v8::Undefined(); // Use the default Number toLocaleString()
442 GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
444 uint16_t format = 'f';
445 if (args.Length() > 1) {
446 if (!args[1]->IsString())
447 V8THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
448 v8::Local<v8::String> fs = args[1]->ToString();
449 if (!fs.IsEmpty() && fs->Length())
450 format = fs->GetCharacter(0);
453 if (args.Length() > 2) {
454 if (!args[2]->IsNumber())
455 V8THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
456 prec = args[2]->IntegerValue();
459 return r->engine->toString(r->locale.toString(number, (char)format, prec));
462 v8::Handle<v8::Value> QQmlNumberExtension::toLocaleCurrencyString(const v8::Arguments& args)
464 if (args.Length() > 2)
465 V8THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
467 double number = args.This()->ToNumber()->Value();
469 if (args.Length() == 0) {
470 // Use QLocale for standard toLocaleString() function
472 return QJSConverter::toString(locale.toString(number));
475 if (!isLocaleObject(args[0]))
476 V8THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
478 GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
481 if (args.Length() > 1) {
482 if (!args[1]->IsString())
483 V8THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
484 symbol = r->engine->toString(args[1]->ToString());
487 return r->engine->toString(r->locale.toCurrencyString(number, symbol));
490 v8::Handle<v8::Value> QQmlNumberExtension::fromLocaleString(const v8::Arguments& args)
492 if (args.Length() < 1 || args.Length() > 2)
493 V8THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
498 if (args.Length() == 2) {
499 if (!isLocaleObject(args[0]))
500 V8THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
502 GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
508 v8::Local<v8::String> ns = args[numberIdx]->ToString();
509 if (ns.IsEmpty() || ns->Length() == 0)
510 return v8::Number::New(Q_QNAN);
513 double val = locale.toDouble(QJSConverter::toString(ns), &ok);
516 V8THROW_ERROR("Locale: Number.fromLocaleString(): Invalid format")
518 return v8::Number::New(val);
524 static v8::Handle<v8::Value> locale_get_firstDayOfWeek(v8::Local<v8::String>, const v8::AccessorInfo &info)
526 GET_LOCALE_DATA_RESOURCE(info.This());
527 return v8::Integer::New(r->locale.firstDayOfWeek());
530 static v8::Handle<v8::Value> locale_get_measurementSystem(v8::Local<v8::String>, const v8::AccessorInfo &info)
532 GET_LOCALE_DATA_RESOURCE(info.This());
533 return v8::Integer::New(r->locale.measurementSystem());
536 static v8::Handle<v8::Value> locale_get_textDirection(v8::Local<v8::String>, const v8::AccessorInfo &info)
538 GET_LOCALE_DATA_RESOURCE(info.This());
539 return v8::Integer::New(r->locale.textDirection());
542 static v8::Handle<v8::Value> locale_get_weekDays(v8::Local<v8::String>, const v8::AccessorInfo &info)
544 GET_LOCALE_DATA_RESOURCE(info.This());
546 QList<Qt::DayOfWeek> days = r->locale.weekdays();
548 v8::Handle<v8::Array> result = v8::Array::New(days.size());
549 for (int i = 0; i < days.size(); ++i) {
550 int day = days.at(i);
551 if (day == 7) // JS Date days in range 0(Sunday) to 6(Saturday)
553 result->Set(i, v8::Integer::New(day));
559 static v8::Handle<v8::Value> locale_get_uiLanguages(v8::Local<v8::String>, const v8::AccessorInfo &info)
561 GET_LOCALE_DATA_RESOURCE(info.This());
563 QStringList langs = r->locale.uiLanguages();
564 v8::Handle<v8::Array> result = v8::Array::New(langs.size());
565 for (int i = 0; i < langs.size(); ++i) {
566 result->Set(i, r->engine->toString(langs.at(i)));
572 static v8::Handle<v8::Value> locale_currencySymbol(const v8::Arguments &args)
574 GET_LOCALE_DATA_RESOURCE(args.This());
576 if (args.Length() > 1)
577 V8THROW_ERROR("Locale: currencySymbol(): Invalid arguments");
579 QLocale::CurrencySymbolFormat format = QLocale::CurrencySymbol;
580 if (args.Length() == 1) {
581 quint32 intFormat = args[0]->ToNumber()->Value();
582 format = QLocale::CurrencySymbolFormat(intFormat);
585 return r->engine->toString(r->locale.currencySymbol(format));
588 #define LOCALE_FORMAT(FUNC) \
589 static v8::Handle<v8::Value> locale_ ##FUNC (const v8::Arguments &args) { \
590 GET_LOCALE_DATA_RESOURCE(args.This());\
591 if (args.Length() > 1) \
592 V8THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \
593 QLocale::FormatType format = QLocale::LongFormat;\
594 if (args.Length() == 1) { \
595 quint32 intFormat = args[0]->Uint32Value(); \
596 format = QLocale::FormatType(intFormat); \
598 return r->engine->toString(r->locale. FUNC (format)); \
601 LOCALE_FORMAT(dateTimeFormat)
602 LOCALE_FORMAT(timeFormat)
603 LOCALE_FORMAT(dateFormat)
605 // +1 added to idx because JS is 0-based, whereas QLocale months begin at 1.
606 #define LOCALE_FORMATTED_MONTHNAME(VARIABLE) \
607 static v8::Handle<v8::Value> locale_ ## VARIABLE (const v8::Arguments &args) {\
608 GET_LOCALE_DATA_RESOURCE(args.This()); \
609 if (args.Length() < 1 || args.Length() > 2) \
610 V8THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
611 QLocale::FormatType enumFormat = QLocale::LongFormat; \
612 int idx = args[0]->IntegerValue() + 1; \
613 if (idx < 1 || idx > 12) \
614 V8THROW_ERROR("Locale: Invalid month"); \
616 if (args.Length() == 2) { \
617 if (args[1]->IsNumber()) { \
618 quint32 intFormat = args[1]->IntegerValue(); \
619 QLocale::FormatType format = QLocale::FormatType(intFormat); \
620 name = r->locale. VARIABLE(idx, format); \
622 V8THROW_ERROR("Locale: Invalid datetime format"); \
625 name = r->locale. VARIABLE(idx, enumFormat); \
627 return r->engine->toString(name); \
630 // 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date
631 #define LOCALE_FORMATTED_DAYNAME(VARIABLE) \
632 static v8::Handle<v8::Value> locale_ ## VARIABLE (const v8::Arguments &args) {\
633 GET_LOCALE_DATA_RESOURCE(args.This()); \
634 if (args.Length() < 1 || args.Length() > 2) \
635 V8THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
636 QLocale::FormatType enumFormat = QLocale::LongFormat; \
637 int idx = args[0]->IntegerValue(); \
638 if (idx < 0 || idx > 7) \
639 V8THROW_ERROR("Locale: Invalid day"); \
640 if (idx == 0) idx = 7; \
642 if (args.Length() == 2) { \
643 if (args[1]->IsNumber()) { \
644 quint32 intFormat = args[1]->ToNumber()->Value(); \
645 QLocale::FormatType format = QLocale::FormatType(intFormat); \
646 name = r->locale. VARIABLE(idx, format); \
648 V8THROW_ERROR("Locale: Invalid datetime format"); \
651 name = r->locale. VARIABLE(idx, enumFormat); \
653 return r->engine->toString(name); \
657 #define LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(FT, VARIABLE, ENGINE) \
658 FT->PrototypeTemplate()->Set(v8::String::New( #VARIABLE ), V8FUNCTION(locale_ ## VARIABLE, ENGINE));
660 LOCALE_FORMATTED_MONTHNAME(monthName)
661 LOCALE_FORMATTED_MONTHNAME(standaloneMonthName)
662 LOCALE_FORMATTED_DAYNAME(dayName)
663 LOCALE_FORMATTED_DAYNAME(standaloneDayName)
665 #define LOCALE_STRING_PROPERTY(VARIABLE) static v8::Handle<v8::Value> locale_get_ ## VARIABLE (v8::Local<v8::String>, const v8::AccessorInfo &info) \
667 GET_LOCALE_DATA_RESOURCE(info.This()); \
668 return r->engine->toString(r->locale. VARIABLE());\
671 #define LOCALE_REGISTER_STRING_ACCESSOR(FT, VARIABLE) \
672 FT ->PrototypeTemplate()->SetAccessor( v8::String::New( #VARIABLE ), locale_get_ ## VARIABLE )
675 LOCALE_STRING_PROPERTY(name)
676 LOCALE_STRING_PROPERTY(nativeLanguageName)
677 LOCALE_STRING_PROPERTY(nativeCountryName)
678 LOCALE_STRING_PROPERTY(decimalPoint)
679 LOCALE_STRING_PROPERTY(groupSeparator)
680 LOCALE_STRING_PROPERTY(percent)
681 LOCALE_STRING_PROPERTY(zeroDigit)
682 LOCALE_STRING_PROPERTY(negativeSign)
683 LOCALE_STRING_PROPERTY(positiveSign)
684 LOCALE_STRING_PROPERTY(exponential)
685 LOCALE_STRING_PROPERTY(amText)
686 LOCALE_STRING_PROPERTY(pmText)
688 class QV8LocaleDataDeletable : public QV8Engine::Deletable
691 QV8LocaleDataDeletable(QV8Engine *engine);
692 ~QV8LocaleDataDeletable();
694 v8::Persistent<v8::Function> constructor;
697 QV8LocaleDataDeletable::QV8LocaleDataDeletable(QV8Engine *engine)
699 v8::HandleScope handle_scope;
700 v8::Context::Scope scope(engine->context());
702 v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
703 ft->InstanceTemplate()->SetHasExternalResource(true);
705 LOCALE_REGISTER_STRING_ACCESSOR(ft, name);
706 LOCALE_REGISTER_STRING_ACCESSOR(ft, nativeLanguageName);
707 LOCALE_REGISTER_STRING_ACCESSOR(ft, nativeCountryName);
708 LOCALE_REGISTER_STRING_ACCESSOR(ft, decimalPoint);
709 LOCALE_REGISTER_STRING_ACCESSOR(ft, groupSeparator);
710 LOCALE_REGISTER_STRING_ACCESSOR(ft, percent);
711 LOCALE_REGISTER_STRING_ACCESSOR(ft, zeroDigit);
712 LOCALE_REGISTER_STRING_ACCESSOR(ft, negativeSign);
713 LOCALE_REGISTER_STRING_ACCESSOR(ft, positiveSign);
714 LOCALE_REGISTER_STRING_ACCESSOR(ft, exponential);
715 LOCALE_REGISTER_STRING_ACCESSOR(ft, amText);
716 LOCALE_REGISTER_STRING_ACCESSOR(ft, pmText);
718 ft->PrototypeTemplate()->Set(v8::String::New("currencySymbol"), V8FUNCTION(locale_currencySymbol, engine));
720 ft->PrototypeTemplate()->Set(v8::String::New("dateTimeFormat"), V8FUNCTION(locale_dateTimeFormat, engine));
721 ft->PrototypeTemplate()->Set(v8::String::New("dateFormat"), V8FUNCTION(locale_dateFormat, engine));
722 ft->PrototypeTemplate()->Set(v8::String::New("timeFormat"), V8FUNCTION(locale_timeFormat, engine));
724 LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(ft, monthName, engine);
725 LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(ft, standaloneMonthName, engine);
726 LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(ft, dayName, engine);
727 LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(ft, standaloneDayName, engine);
729 ft->PrototypeTemplate()->SetAccessor(v8::String::New("firstDayOfWeek"), locale_get_firstDayOfWeek);
730 ft->PrototypeTemplate()->SetAccessor(v8::String::New("weekDays"), locale_get_weekDays);
731 ft->PrototypeTemplate()->SetAccessor(v8::String::New("measurementSystem"), locale_get_measurementSystem);
732 ft->PrototypeTemplate()->SetAccessor(v8::String::New("textDirection"), locale_get_textDirection);
733 ft->PrototypeTemplate()->SetAccessor(v8::String::New("uiLanguages"), locale_get_uiLanguages);
735 constructor = qPersistentNew(ft->GetFunction());
738 QV8LocaleDataDeletable::~QV8LocaleDataDeletable()
740 qPersistentDispose(constructor);
743 V8_DEFINE_EXTENSION(QV8LocaleDataDeletable, localeV8Data);
746 \qmlclass Locale QQmlLocale
747 \inqmlmodule QtQuick 2
748 \brief The Locale object provides locale specific properties and formatted data.
750 The Locale object is created via the \l{QML:Qt::locale()}{Qt.locale()} function. It cannot be created
753 The \l{QML:Qt::locale()}{Qt.locale()} function returns a JS Locale object representing the
754 locale with the specified name, which has the format
755 "language[_territory][.codeset][@modifier]" or "C".
757 Locale supports the concept of a default locale, which is
758 determined from the system's locale settings at application
759 startup. If no parameter is passed to Qt.locale() the default
760 locale object is returned.
762 The Locale object provides a number of functions and properties
763 providing data for the specified locale.
765 The Locale object may also be passed to the \l Date and \l Number toLocaleString()
766 and fromLocaleString() methods in order to convert to/from strings using
767 the specified locale.
769 This example shows the current date formatted for the German locale:
775 text: "The date is: " + Date().toLocaleString(Qt.locale("de_DE"))
779 The following example displays the specified number
780 in the correct format for the default locale:
786 text: "The value is: " + Number(23443.34).toLocaleString(Qt.locale())
790 QtQuick Locale's data is based on Common Locale Data Repository v1.8.1.
792 The double-to-string and string-to-double conversion functions are
793 covered by the following licenses:
796 Copyright (c) 1991 by AT&T.
798 Permission to use, copy, modify, and distribute this software for any
799 purpose without fee is hereby granted, provided that this entire notice
800 is included in all copies of any software which is or includes a copy
801 or modification of this software and in all copies of the supporting
802 documentation for such software.
804 THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
805 WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
806 REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
807 OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
809 This product includes software developed by the University of
810 California, Berkeley and its contributors.
812 \sa {QtQuick2::Date}{Date} {QtQuick2::Number}{Number}
815 QQmlLocale::QQmlLocale()
819 QQmlLocale::~QQmlLocale()
823 v8::Handle<v8::Value> QQmlLocale::locale(QV8Engine *v8engine, const QString &locale)
825 QV8LocaleDataDeletable *d = localeV8Data(v8engine);
826 v8::Local<v8::Object> v8Value = d->constructor->NewInstance();
827 QV8LocaleDataResource *r = new QV8LocaleDataResource(v8engine);
828 if (locale.isEmpty())
829 r->locale = QLocale();
831 r->locale = QLocale(locale);
832 v8Value->SetExternalResource(r);
837 static const char *localeCompareFunction =
838 "(function(localeCompareFunc) { "
839 " var orig_localeCompare;"
840 " orig_localeCompare = String.prototype.localeCompare;"
841 " String.prototype.localeCompare = (function() {"
842 " var val = localeCompareFunc.apply(this, arguments);"
843 " if (val == undefined) val = orig_localeCompare.call(this);"
848 void QQmlLocale::registerStringLocaleCompare(QV8Engine *engine)
850 registerFunction(engine, localeCompareFunction, localeCompare);
853 v8::Handle<v8::Value> QQmlLocale::localeCompare(const v8::Arguments &args)
855 if (args.Length() != 1 || (!args[0]->IsString() && !args[0]->IsStringObject()))
856 return v8::Undefined();
858 if (!args.This()->IsString() && !args.This()->IsStringObject())
859 return v8::Undefined();
861 QString thisString = QJSConverter::toString(args.This()->ToString());
862 QString thatString = QJSConverter::toString(args[0]->ToString());
864 return v8::Integer::New(QString::localeAwareCompare(thisString, thatString));
868 \enum QtQuick2::Locale::FormatType
870 This enumeration describes the types of format that can be used when
871 converting Date objects to strings.
873 \value LongFormat The long version of day and month names; for
874 example, returning "January" as a month name.
876 \value ShortFormat The short version of day and month names; for
877 example, returning "Jan" as a month name.
879 \value NarrowFormat A special version of day and month names for
880 use when space is limited; for example, returning "J" as a month
881 name. Note that the narrow format might contain the same text for
882 different months and days or it can even be an empty string if the
883 locale doesn't support narrow names, so you should avoid using it
884 for date formatting. Also, for the system locale this format is
885 the same as ShortFormat.
889 \qmlproperty string QtQuick2::Locale::name
891 Holds the language and country of this locale as a
892 string of the form "language_country", where
893 language is a lowercase, two-letter ISO 639 language code,
894 and country is an uppercase, two- or three-letter ISO 3166 country code.
898 \qmlproperty string QtQuick2::Locale::decimalPoint
900 Holds the decimal point character of this locale.
904 \qmlproperty string QtQuick2::Locale::groupSeparator
906 Holds the group separator character of this locale.
910 \qmlproperty string QtQuick2::Locale::percent
912 Holds the percent character of this locale.
917 \qmlproperty string QtQuick2::Locale::zeroDigit
919 Holds Returns the zero digit character of this locale.
923 \qmlproperty string QtQuick2::Locale::negativeSign
925 Holds the negative sign character of this locale.
929 \qmlproperty string QtQuick2::Locale::positiveSign
931 Holds the positive sign character of this locale.
935 \qmlproperty string QtQuick2::Locale::exponential
937 Holds the exponential character of this locale.
941 \qmlmethod string QtQuick2::Locale::dateTimeFormat(type)
943 Returns the date time format used for the current locale.
944 \a type specifies the FormatType to return.
946 \sa {QtQuick2::Date}{Date}
950 \qmlmethod string QtQuick2::Locale::dateFormat(type)
952 Returns the date format used for the current locale.
953 \a type specifies the FormatType to return.
955 \sa {QtQuick2::Date}{Date}
959 \qmlmethod string QtQuick2::Locale::timeFormat(type)
961 Returns the time format used for the current locale.
962 \a type specifies the FormatType to return.
964 \sa {QtQuick2::Date}{Date}
968 \qmlmethod string QtQuick2::Locale::monthName(month, type)
970 Returns the localized name of \a month (0-11), in the optional
971 \l FortmatType specified by \a type.
973 \note the QLocale C++ API expects a range of (1-12), however Locale.monthName()
974 expects 0-11 as per the JS Date object.
976 \sa dayName(), standaloneMonthName()
980 \qmlmethod string QtQuick2::Locale::standaloneMonthName(month, type)
982 Returns the localized name of \a month (0-11) that is used as a
983 standalone text, in the optional \l FormatType specified by \a type.
985 If the locale information doesn't specify the standalone month
986 name then return value is the same as in monthName().
988 \note the QLocale C++ API expects a range of (1-12), however Locale.standaloneMonthName()
989 expects 0-11 as per the JS Date object.
991 \sa monthName(), standaloneDayName()
995 \qmlmethod string QtQuick2::Locale::dayName(day, type)
997 Returns the localized name of the \a day (where 0 represents
998 Sunday, 1 represents Monday and so on), in the optional
999 \l FormatType specified by \a type.
1001 \sa monthName(), standaloneDayName()
1005 \qmlmethod string QtQuick2::Locale::standaloneDayName(day, type)
1007 Returns the localized name of the \a day (where 0 represents
1008 Sunday, 1 represents Monday and so on) that is used as a
1009 standalone text, in the \l FormatType specified by \a type.
1011 If the locale information does not specify the standalone day
1012 name then return value is the same as in dayName().
1014 \sa dayName(), standaloneMonthName()
1018 \qmlproperty enumeration QtQuick2::Locale::firstDayOfWeek
1020 Holds the first day of the week according to the current locale.
1023 \o Locale.Sunday = 0
1024 \o Locale.Monday = 1
1025 \o Locale.Tuesday = 2
1026 \o Locale.Wednesday = 3
1027 \o Locale.Thursday = 4
1028 \o Locale.Friday = 5
1029 \o Locale.Saturday = 6
1032 \note that these values match the JS Date API which is different
1033 from the Qt C++ API where Qt::Sunday = 7.
1037 \qmlproperty Array<int> QtQuick2::Locale::weekDays
1039 Holds an array of days that are considered week days according to the current locale,
1040 where Sunday is 0 and Saturday is 6.
1046 \qmlproperty Array<string> QtQuick2::Locale::uiLanguages
1048 Returns an ordered list of locale names for translation purposes in
1051 The return value represents locale names that the user expects to see the
1054 The first item in the list is the most preferred one.
1058 \qmlproperty enumeration QtQuick2::Locale::textDirection
1060 Holds the text direction of the language:
1068 \qmlproperty string QtQuick2::Locale::amText
1070 The localized name of the "AM" suffix for times specified using the conventions of the 12-hour clock.
1074 \qmlproperty string QtQuick2::Locale::pmText
1076 The localized name of the "PM" suffix for times specified using the conventions of the 12-hour clock.
1080 \qmlmethod string QtQuick2::Locale::currencySymbol(format)
1082 Returns the currency symbol for the specified \a format:
1084 \o Locale.CurrencyIsoCode a ISO-4217 code of the currency.
1085 \o Locale.CurrencySymbol a currency symbol.
1086 \o Locale.CurrencyDisplayName a user readable name of the currency.
1088 \sa Number::toLocaleCurrencyString()
1092 \qmlproperty string QtQuick2::Locale::nativeLanguageName
1094 Holds a native name of the language for the locale. For example
1095 "Schwiizertüütsch" for Swiss-German locale.
1097 \sa nativeCountryName
1101 \qmlproperty string QtQuick2::Locale::nativeCountryName
1103 Holds a native name of the country for the locale. For example
1104 "España" for Spanish/Spain locale.
1106 \sa nativeLanguageName
1110 \qmlproperty enumeration QtQuick2::Locale::measurementSystem
1112 This property defines which units are used for measurement.
1115 \o Locale.MetricSystem This value indicates metric units, such as meters,
1116 centimeters and millimeters.
1117 \o Locale.ImperialSystem This value indicates imperial units, such as inches and
1118 miles. There are several distinct imperial systems in the world; this
1119 value stands for the official United States imperial units.