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 QtDeclarative 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 "qdeclarativelocale_p.h"
43 #include "qdeclarativeengine_p.h"
44 #include <private/qdeclarativecontext_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 QDeclarativeDateExtension::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> QDeclarativeDateExtension::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> QDeclarativeDateExtension::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> QDeclarativeDateExtension::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> QDeclarativeDateExtension::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> QDeclarativeDateExtension::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> QDeclarativeDateExtension::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 QDeclarativeNumberExtension::registerExtension(QV8Engine *engine)
421 registerFunction(engine, numberToLocaleStringFunction, toLocaleString);
422 registerFunction(engine, numberToLocaleCurrencyStringFunction, toLocaleCurrencyString);
423 registerFunction(engine, numberFromLocaleStringFunction, fromLocaleString);
426 v8::Handle<v8::Value> QDeclarativeNumberExtension::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> QDeclarativeNumberExtension::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> QDeclarativeNumberExtension::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_currencySymbol(const v8::Arguments &args)
561 GET_LOCALE_DATA_RESOURCE(args.This());
563 if (args.Length() > 1)
564 V8THROW_ERROR("Locale: currencySymbol(): Invalid arguments");
566 QLocale::CurrencySymbolFormat format = QLocale::CurrencySymbol;
567 if (args.Length() == 1) {
568 quint32 intFormat = args[0]->ToNumber()->Value();
569 format = QLocale::CurrencySymbolFormat(intFormat);
572 return r->engine->toString(r->locale.currencySymbol(format));
575 #define LOCALE_FORMAT(FUNC) \
576 static v8::Handle<v8::Value> locale_ ##FUNC (const v8::Arguments &args) { \
577 GET_LOCALE_DATA_RESOURCE(args.This());\
578 if (args.Length() > 1) \
579 V8THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \
580 QLocale::FormatType format = QLocale::LongFormat;\
581 if (args.Length() == 1) { \
582 quint32 intFormat = args[0]->Uint32Value(); \
583 format = QLocale::FormatType(intFormat); \
585 return r->engine->toString(r->locale. FUNC (format)); \
588 LOCALE_FORMAT(dateTimeFormat)
589 LOCALE_FORMAT(timeFormat)
590 LOCALE_FORMAT(dateFormat)
592 // +1 added to idx because JS is 0-based, whereas QLocale months begin at 1.
593 #define LOCALE_FORMATTED_MONTHNAME(VARIABLE) \
594 static v8::Handle<v8::Value> locale_ ## VARIABLE (const v8::Arguments &args) {\
595 GET_LOCALE_DATA_RESOURCE(args.This()); \
596 if (args.Length() < 1 || args.Length() > 2) \
597 V8THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
598 QLocale::FormatType enumFormat = QLocale::LongFormat; \
599 int idx = args[0]->IntegerValue() + 1; \
600 if (idx < 1 || idx > 12) \
601 V8THROW_ERROR("Locale: Invalid month"); \
603 if (args.Length() == 2) { \
604 if (args[1]->IsNumber()) { \
605 quint32 intFormat = args[1]->IntegerValue(); \
606 QLocale::FormatType format = QLocale::FormatType(intFormat); \
607 name = r->locale. VARIABLE(idx, format); \
609 V8THROW_ERROR("Locale: Invalid datetime format"); \
612 name = r->locale. VARIABLE(idx, enumFormat); \
614 return r->engine->toString(name); \
617 // 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date
618 #define LOCALE_FORMATTED_DAYNAME(VARIABLE) \
619 static v8::Handle<v8::Value> locale_ ## VARIABLE (const v8::Arguments &args) {\
620 GET_LOCALE_DATA_RESOURCE(args.This()); \
621 if (args.Length() < 1 || args.Length() > 2) \
622 V8THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
623 QLocale::FormatType enumFormat = QLocale::LongFormat; \
624 int idx = args[0]->IntegerValue(); \
625 if (idx < 0 || idx > 7) \
626 V8THROW_ERROR("Locale: Invalid day"); \
627 if (idx == 0) idx = 7; \
629 if (args.Length() == 2) { \
630 if (args[1]->IsNumber()) { \
631 quint32 intFormat = args[1]->ToNumber()->Value(); \
632 QLocale::FormatType format = QLocale::FormatType(intFormat); \
633 name = r->locale. VARIABLE(idx, format); \
635 V8THROW_ERROR("Locale: Invalid datetime format"); \
638 name = r->locale. VARIABLE(idx, enumFormat); \
640 return r->engine->toString(name); \
644 #define LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(FT, VARIABLE, ENGINE) \
645 FT->PrototypeTemplate()->Set(v8::String::New( #VARIABLE ), V8FUNCTION(locale_ ## VARIABLE, ENGINE));
647 LOCALE_FORMATTED_MONTHNAME(monthName)
648 LOCALE_FORMATTED_MONTHNAME(standaloneMonthName)
649 LOCALE_FORMATTED_DAYNAME(dayName)
650 LOCALE_FORMATTED_DAYNAME(standaloneDayName)
652 #define LOCALE_STRING_PROPERTY(VARIABLE) static v8::Handle<v8::Value> locale_get_ ## VARIABLE (v8::Local<v8::String>, const v8::AccessorInfo &info) \
654 GET_LOCALE_DATA_RESOURCE(info.This()); \
655 return r->engine->toString(r->locale. VARIABLE());\
658 #define LOCALE_REGISTER_STRING_ACCESSOR(FT, VARIABLE) \
659 FT ->PrototypeTemplate()->SetAccessor( v8::String::New( #VARIABLE ), locale_get_ ## VARIABLE )
662 LOCALE_STRING_PROPERTY(name)
663 LOCALE_STRING_PROPERTY(nativeLanguageName)
664 LOCALE_STRING_PROPERTY(nativeCountryName)
665 LOCALE_STRING_PROPERTY(decimalPoint)
666 LOCALE_STRING_PROPERTY(groupSeparator)
667 LOCALE_STRING_PROPERTY(percent)
668 LOCALE_STRING_PROPERTY(zeroDigit)
669 LOCALE_STRING_PROPERTY(negativeSign)
670 LOCALE_STRING_PROPERTY(positiveSign)
671 LOCALE_STRING_PROPERTY(exponential)
672 LOCALE_STRING_PROPERTY(amText)
673 LOCALE_STRING_PROPERTY(pmText)
675 class QV8LocaleDataDeletable : public QV8Engine::Deletable
678 QV8LocaleDataDeletable(QV8Engine *engine);
679 ~QV8LocaleDataDeletable();
681 v8::Persistent<v8::Function> constructor;
684 QV8LocaleDataDeletable::QV8LocaleDataDeletable(QV8Engine *engine)
686 v8::HandleScope handle_scope;
687 v8::Context::Scope scope(engine->context());
689 v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
690 ft->InstanceTemplate()->SetHasExternalResource(true);
692 LOCALE_REGISTER_STRING_ACCESSOR(ft, name);
693 LOCALE_REGISTER_STRING_ACCESSOR(ft, nativeLanguageName);
694 LOCALE_REGISTER_STRING_ACCESSOR(ft, nativeCountryName);
695 LOCALE_REGISTER_STRING_ACCESSOR(ft, decimalPoint);
696 LOCALE_REGISTER_STRING_ACCESSOR(ft, groupSeparator);
697 LOCALE_REGISTER_STRING_ACCESSOR(ft, percent);
698 LOCALE_REGISTER_STRING_ACCESSOR(ft, zeroDigit);
699 LOCALE_REGISTER_STRING_ACCESSOR(ft, negativeSign);
700 LOCALE_REGISTER_STRING_ACCESSOR(ft, positiveSign);
701 LOCALE_REGISTER_STRING_ACCESSOR(ft, exponential);
702 LOCALE_REGISTER_STRING_ACCESSOR(ft, amText);
703 LOCALE_REGISTER_STRING_ACCESSOR(ft, pmText);
705 ft->PrototypeTemplate()->Set(v8::String::New("currencySymbol"), V8FUNCTION(locale_currencySymbol, engine));
707 ft->PrototypeTemplate()->Set(v8::String::New("dateTimeFormat"), V8FUNCTION(locale_dateTimeFormat, engine));
708 ft->PrototypeTemplate()->Set(v8::String::New("dateFormat"), V8FUNCTION(locale_dateFormat, engine));
709 ft->PrototypeTemplate()->Set(v8::String::New("timeFormat"), V8FUNCTION(locale_timeFormat, engine));
711 LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(ft, monthName, engine);
712 LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(ft, standaloneMonthName, engine);
713 LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(ft, dayName, engine);
714 LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(ft, standaloneDayName, engine);
716 ft->PrototypeTemplate()->SetAccessor(v8::String::New("firstDayOfWeek"), locale_get_firstDayOfWeek);
717 ft->PrototypeTemplate()->SetAccessor(v8::String::New("weekDays"), locale_get_weekDays);
718 ft->PrototypeTemplate()->SetAccessor(v8::String::New("measurementSystem"), locale_get_measurementSystem);
719 ft->PrototypeTemplate()->SetAccessor(v8::String::New("textDirection"), locale_get_textDirection);
721 constructor = qPersistentNew(ft->GetFunction());
724 QV8LocaleDataDeletable::~QV8LocaleDataDeletable()
726 qPersistentDispose(constructor);
729 V8_DEFINE_EXTENSION(QV8LocaleDataDeletable, localeV8Data);
732 \qmlclass Locale QDeclarativeLocale
733 \inqmlmodule QtQuick 2
734 \brief The Locale object provides locale specific properties and formatted data.
736 The Locale object is created via the \l{QML:Qt::locale()}{Qt.locale()} function. It cannot be created
739 The \l{QML:Qt::locale()}{Qt.locale()} function returns a JS Locale object representing the
740 locale with the specified name, which has the format
741 "language[_territory][.codeset][@modifier]" or "C".
743 Locale supports the concept of a default locale, which is
744 determined from the system's locale settings at application
745 startup. If no parameter is passed to Qt.locale() the default
746 locale object is returned.
748 The Locale object provides a number of functions and properties
749 providing data for the specified locale.
751 The Locale object may also be passed to the \l Date and \l Number toLocaleString()
752 and fromLocaleString() methods in order to convert to/from strings using
753 the specified locale.
755 This example shows the current date formatted for the German locale:
761 text: "The date is: " + Date().toLocaleString(Qt.locale("de_DE"))
765 The following example displays the specified number
766 in the correct format for the default locale:
772 text: "The value is: " + Number(23443.34).toLocaleString(Qt.locale())
776 QtQuick Locale's data is based on Common Locale Data Repository v1.8.1.
778 The double-to-string and string-to-double conversion functions are
779 covered by the following licenses:
782 Copyright (c) 1991 by AT&T.
784 Permission to use, copy, modify, and distribute this software for any
785 purpose without fee is hereby granted, provided that this entire notice
786 is included in all copies of any software which is or includes a copy
787 or modification of this software and in all copies of the supporting
788 documentation for such software.
790 THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
791 WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
792 REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
793 OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
795 This product includes software developed by the University of
796 California, Berkeley and its contributors.
798 \sa {QtQuick2::Date}{Date} {QtQuick2::Number}{Number}
801 QDeclarativeLocale::QDeclarativeLocale()
805 QDeclarativeLocale::~QDeclarativeLocale()
809 v8::Handle<v8::Value> QDeclarativeLocale::locale(QV8Engine *v8engine, const QString &locale)
811 QV8LocaleDataDeletable *d = localeV8Data(v8engine);
812 v8::Local<v8::Object> v8Value = d->constructor->NewInstance();
813 QV8LocaleDataResource *r = new QV8LocaleDataResource(v8engine);
814 if (locale.isEmpty())
815 r->locale = QLocale();
817 r->locale = QLocale(locale);
818 v8Value->SetExternalResource(r);
824 \enum QtQuick2::Locale::FormatType
826 This enumeration describes the types of format that can be used when
827 converting Date objects to strings.
829 \value LongFormat The long version of day and month names; for
830 example, returning "January" as a month name.
832 \value ShortFormat The short version of day and month names; for
833 example, returning "Jan" as a month name.
835 \value NarrowFormat A special version of day and month names for
836 use when space is limited; for example, returning "J" as a month
837 name. Note that the narrow format might contain the same text for
838 different months and days or it can even be an empty string if the
839 locale doesn't support narrow names, so you should avoid using it
840 for date formatting. Also, for the system locale this format is
841 the same as ShortFormat.
845 \qmlproperty string QtQuick2::Locale::name
847 Holds the language and country of this locale as a
848 string of the form "language_country", where
849 language is a lowercase, two-letter ISO 639 language code,
850 and country is an uppercase, two- or three-letter ISO 3166 country code.
854 \qmlproperty string QtQuick2::Locale::decimalPoint
856 Holds the decimal point character of this locale.
860 \qmlproperty string QtQuick2::Locale::groupSeparator
862 Holds the group separator character of this locale.
866 \qmlproperty string QtQuick2::Locale::percent
868 Holds the percent character of this locale.
873 \qmlproperty string QtQuick2::Locale::zeroDigit
875 Holds Returns the zero digit character of this locale.
879 \qmlproperty string QtQuick2::Locale::negativeSign
881 Holds the negative sign character of this locale.
885 \qmlproperty string QtQuick2::Locale::positiveSign
887 Holds the positive sign character of this locale.
891 \qmlproperty string QtQuick2::Locale::exponential
893 Holds the exponential character of this locale.
897 \qmlmethod string QtQuick2::Locale::dateTimeFormat(type)
899 Returns the date time format used for the current locale.
900 \a type specifies the FormatType to return.
902 \sa {QtQuick2::Date}{Date}
906 \qmlmethod string QtQuick2::Locale::dateFormat(type)
908 Returns the date format used for the current locale.
909 \a type specifies the FormatType to return.
911 \sa {QtQuick2::Date}{Date}
915 \qmlmethod string QtQuick2::Locale::timeFormat(type)
917 Returns the time format used for the current locale.
918 \a type specifies the FormatType to return.
920 \sa {QtQuick2::Date}{Date}
924 \qmlmethod string QtQuick2::Locale::monthName(month, type)
926 Returns the localized name of \a month (0-11), in the optional
927 \l FortmatType specified by \a type.
929 \note the QLocale C++ API expects a range of (1-12), however Locale.monthName()
930 expects 0-11 as per the JS Date object.
932 \sa dayName(), standaloneMonthName()
936 \qmlmethod string QtQuick2::Locale::standaloneMonthName(month, type)
938 Returns the localized name of \a month (0-11) that is used as a
939 standalone text, in the optional \l FormatType specified by \a type.
941 If the locale information doesn't specify the standalone month
942 name then return value is the same as in monthName().
944 \note the QLocale C++ API expects a range of (1-12), however Locale.standaloneMonthName()
945 expects 0-11 as per the JS Date object.
947 \sa monthName(), standaloneDayName()
951 \qmlmethod string QtQuick2::Locale::dayName(day, type)
953 Returns the localized name of the \a day (where 0 represents
954 Sunday, 1 represents Monday and so on), in the optional
955 \l FormatType specified by \a type.
957 \sa monthName(), standaloneDayName()
961 \qmlmethod string QtQuick2::Locale::standaloneDayName(day, type)
963 Returns the localized name of the \a day (where 0 represents
964 Sunday, 1 represents Monday and so on) that is used as a
965 standalone text, in the \l FormatType specified by \a type.
967 If the locale information does not specify the standalone day
968 name then return value is the same as in dayName().
970 \sa dayName(), standaloneMonthName()
974 \qmlproperty enumeration QtQuick2::Locale::firstDayOfWeek
976 Holds the first day of the week according to the current locale.
981 \o Locale.Tuesday = 2
982 \o Locale.Wednesday = 3
983 \o Locale.Thursday = 4
985 \o Locale.Saturday = 6
988 \note that these values match the JS Date API which is different
989 from the Qt C++ API where Qt::Sunday = 7.
993 \qmlproperty Array<int> QtQuick2::Locale::weekDays
995 Holds an array of days that are considered week days according to the current locale,
996 where Sunday is 0 and Saturday is 6.
1003 \qmlproperty enumeration QtQuick2::Locale::textDirection
1005 Holds the text direction of the language:
1013 \qmlproperty string QtQuick2::Locale::amText
1015 The localized name of the "AM" suffix for times specified using the conventions of the 12-hour clock.
1019 \qmlproperty string QtQuick2::Locale::pmText
1021 The localized name of the "PM" suffix for times specified using the conventions of the 12-hour clock.
1025 \qmlmethod string QtQuick2::Locale::currencySymbol(format)
1027 Returns the currency symbol for the specified \a format:
1029 \o Locale.CurrencyIsoCode a ISO-4217 code of the currency.
1030 \o Locale.CurrencySymbol a currency symbol.
1031 \o Locale.CurrencyDisplayName a user readable name of the currency.
1033 \sa Number::toLocaleCurrencyString()
1037 \qmlproperty string QtQuick2::Locale::nativeLanguageName
1039 Holds a native name of the language for the locale. For example
1040 "Schwiizertüütsch" for Swiss-German locale.
1042 \sa nativeCountryName
1046 \qmlproperty string QtQuick2::Locale::nativeCountryName
1048 Holds a native name of the country for the locale. For example
1049 "España" for Spanish/Spain locale.
1051 \sa nativeLanguageName
1055 \qmlproperty enumeration QtQuick2::Locale::measurementSystem
1057 This property defines which units are used for measurement.
1060 \o Locale.MetricSystem This value indicates metric units, such as meters,
1061 centimeters and millimeters.
1062 \o Locale.ImperialSystem This value indicates imperial units, such as inches and
1063 miles. There are several distinct imperial systems in the world; this
1064 value stands for the official United States imperial units.