aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/declarative/qdeclarativei18n.qdoc16
-rw-r--r--doc/src/declarative/qmldate.qdoc149
-rw-r--r--doc/src/declarative/qmlnumber.qdoc105
-rw-r--r--doc/src/qtquick1/declarativeui.qdoc2
-rw-r--r--doc/src/qtquick1/qdeclarativei18n.qdoc2
-rw-r--r--examples/declarative/locale/locale.qml132
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp2
-rw-r--r--src/declarative/qml/qdeclarativeengine_p.h3
-rw-r--r--src/declarative/qml/qdeclarativelocale.cpp1095
-rw-r--r--src/declarative/qml/qdeclarativelocale_p.h132
-rw-r--r--src/declarative/qml/qml.pri4
-rw-r--r--src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp43
-rw-r--r--src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h1
-rw-r--r--src/declarative/qml/v8/qjsengine.cpp3
-rw-r--r--src/declarative/qml/v8/qjsengine.h4
-rw-r--r--src/declarative/qml/v8/qjsengine_p.h57
-rw-r--r--src/declarative/qml/v8/qv8engine.cpp8
-rw-r--r--src/declarative/qml/v8/qv8engine_p.h6
-rw-r--r--src/declarative/qml/v8/script.pri1
-rw-r--r--tests/auto/declarative/declarative.pro1
-rw-r--r--tests/auto/declarative/qdeclarativelocale/data/date.qml45
-rw-r--r--tests/auto/declarative/qdeclarativelocale/data/functions.qml65
-rw-r--r--tests/auto/declarative/qdeclarativelocale/data/number.qml30
-rw-r--r--tests/auto/declarative/qdeclarativelocale/data/properties.qml26
-rw-r--r--tests/auto/declarative/qdeclarativelocale/qdeclarativelocale.pro13
-rw-r--r--tests/auto/declarative/qdeclarativelocale/tst_qdeclarativelocale.cpp1090
26 files changed, 3024 insertions, 11 deletions
diff --git a/doc/src/declarative/qdeclarativei18n.qdoc b/doc/src/declarative/qdeclarativei18n.qdoc
index 00422002c3..79a935657d 100644
--- a/doc/src/declarative/qdeclarativei18n.qdoc
+++ b/doc/src/declarative/qdeclarativei18n.qdoc
@@ -34,6 +34,7 @@
\nextpage {QML Features}
\title QML Internationalization
+\section1 Translation
Strings in QML can be marked for translation using the qsTr(), qsTranslate(),
QT_TR_NOOP(), and QT_TRANSLATE_NOOP() functions.
@@ -55,14 +56,14 @@ capabilities are described more fully in:
You can test a translation with the \l {QML Viewer} using the -translation option.
-\section1 Example
+\section2 Example
First we create a simple QML file with text to be translated. The string
that needs to be translated is enclosed in a call to \c qsTr().
hello.qml:
\qml
-import QtQuick 1.0
+import QtQuick 2.0
Rectangle {
width: 200; height: 200
@@ -83,6 +84,15 @@ Finally, we can test the translation:
qmlviewer -translation hello.qm hello.qml
\endcode
-
You can see a complete example and source code in the \l{declarative/i18n}{QML Internationalization example}.
+
+\section1 Localization
+
+Localization is the process of adapting to local conventions,
+for example presenting dates and times using the locally preferred formats.
+
+Qt Quick supports localization via the \l {QtQuick2::Locale}{Locale} object and extensions to the
+ECMAScript \l {QtQuick2::Date}{Date} and \l {QtQuick2::Number}{Number} types.
+
+
*/
diff --git a/doc/src/declarative/qmldate.qdoc b/doc/src/declarative/qmldate.qdoc
new file mode 100644
index 0000000000..c0552aad40
--- /dev/null
+++ b/doc/src/declarative/qmldate.qdoc
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms
+** and conditions contained in a signed written agreement between you
+** and Nokia.
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \qmlclass Date
+ \inqmlmodule QtQuick 2
+ \brief The Date object provides date functions
+
+ The QML Date object extends the JS Date object with
+ locale aware functions.
+
+ Functions that accept a locale format may be either an enumeration
+ value:
+ \table
+ \row \i Locale.LongFormat \i The long version of day and month names; for example, returning "January" as a month name.
+ \row \i Locale.ShortFormat \i The short version of day and month names; for example, returning "Jan" as a month name.
+ \row \i Locale.NarrowFormat \i A special version of day and month names for use when space is limited;
+ for example, returning "J" as a month name. Note that the narrow format might contain
+ the same text for different months and days or it can even be an empty string if the
+ locale doesn't support narrow names, so you should avoid using it for date formatting.
+ Also, for the system locale this format is the same as ShortFormat.
+ \endtable
+
+ or a string specifying the format:
+ \table
+ \header \i Expression \i Output
+ \row \i d \i the day as number without a leading zero (1 to 31)
+ \row \i dd \i the day as number with a leading zero (01 to 31)
+ \row \i ddd
+ \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ \row \i dddd
+ \i the long localized day name (e.g. 'Monday' to 'Sunday').
+ \row \i M \i the month as number without a leading zero (1 to 12)
+ \row \i MM \i the month as number with a leading zero (01 to 12)
+ \row \i MMM
+ \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ \row \i MMMM
+ \i the long localized month name (e.g. 'January' to 'December').
+ \row \i yy \i the year as two digit number (00 to 99)
+ \row \i yyyy \i the year as four digit number. If the year is negative,
+ a minus sign is prepended in addition.
+ \endtable
+
+ All other input characters will be ignored. Any sequence of characters that
+ are enclosed in singlequotes will be treated as text and not be used as an
+ expression. Two consecutive singlequotes ("''") are replaced by a singlequote
+ in the output.
+
+ Example format strings (assuming that the Date is the 20 July
+ 1969):
+
+ \table
+ \header \o Format \o Result
+ \row \o dd.MM.yyyy \o 20.07.1969
+ \row \o ddd MMMM d yy \o Sun July 20 69
+ \row \o 'The day is' dddd \o The day is Sunday
+ \endtable
+
+ \sa {QtQuick2::Locale}{Locale}
+*/
+
+/*!
+ \qmlmethod string Date::toLocaleString(locale,format)
+
+ Converts the Date to a string containing the date and time
+ suitable for the specified \a locale
+ in the specified \a format.
+
+ If the format is not specified Locale.LongFormat will be used.
+
+ If \a locale is not specified, the default locale will be used.
+
+ The following example shows the current date and time formatted
+ for the German locale:
+ \code
+ import QtQuick 2.0
+
+ Text {
+ text: "The date is: " + Date().toLocaleString(Qt.locale("de_DE"))
+ }
+ \endcode
+*/
+
+/*!
+ \qmlmethod string Date::toLocaleDateString(locale,format)
+
+ Converts the Date to a string containing the date suitable for the specified \a locale
+ in the specified \a format.
+
+ If the format is not specified Locale.LongFormat will be used.
+
+ If \a locale is not specified, the default locale will be used.
+
+ The following example shows the current date formatted
+ for the German locale:
+ \code
+ import QtQuick 2.0
+
+ Text {
+ text: "The date is: " + Date().toLocaleDateString(Qt.locale("de_DE"))
+ }
+ \endcode
+*/
+
+/*!
+ \qmlmethod string Date::toLocaleTimeString(locale,format)
+
+ Converts the Date to a string containing the time suitable for the specified \a locale
+ in the specified \a format.
+
+ If the format is not specified Locale.LongFormat will be used.
+
+ If \a locale is not specified, the default locale will be used.
+
+ The following example shows the current time formatted
+ for the German locale:
+ \code
+ import QtQuick 2.0
+
+ Text {
+ text: "The date is: " + Date().toLocaleTimeString(Qt.locale("de_DE"))
+ }
+ \endcode
+*/
+
diff --git a/doc/src/declarative/qmlnumber.qdoc b/doc/src/declarative/qmlnumber.qdoc
new file mode 100644
index 0000000000..0b4341d76b
--- /dev/null
+++ b/doc/src/declarative/qmlnumber.qdoc
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms
+** and conditions contained in a signed written agreement between you
+** and Nokia.
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \qmlclass Number
+ \inqmlmodule QtQuick 2
+ \brief The Number object provides represents a number value
+
+ The QML Number object extends the JS Number object with
+ locale aware functions.
+
+ \sa {QtQuick2::Locale}{Locale}
+*/
+
+/*!
+ \qmlmethod string Number::toLocaleString(locale,format,precision)
+
+ Converts the Number to a string suitable for the specified \a locale
+ in the specified \a format, with the specified \a precision.
+
+ Valid formats are:
+ \list
+ \o 'f' Decimal floating point, e.g. 248.65
+ \o 'e' Scientific notation using e character, e.g. 2.4865e+2
+ \o 'E' Scientific notation using E character, e.g. 2.4865E+2
+ \o 'g' Use the shorter of e or f
+ \o 'G' Use the shorter of E or f
+ \endlist
+
+ If precision is not specified, the precision will be 2.
+
+ If the format is not specified 'f' will be used.
+
+ If \a locale is not specified, the default locale will be used.
+
+ The following example shows a number formatted for the German locale:
+ \code
+ import QtQuick 2.0
+
+ Text {
+ text: "The value is: " + Number(4742378.423).toLocaleString(Qt.locale("de_DE"))
+ }
+ \endcode
+
+ You can apply toLocaleString() directly to constants, provided the decimal
+ is included in the constant, e.g.
+ \code
+ 123.0.toLocaleString(Qt.locale("de_DE")) // OK
+ 123..toLocaleString(Qt.locale("de_DE")) // OK
+ 123.toLocaleString(Qt.locale("de_DE")) // fails
+ \endcode
+*/
+
+/*!
+ \qmlmethod string Number::toLocaleCurrencyString(locale,symbol)
+
+ Converts the Number to a currency using the currency and conventions of the specified
+ \a locale. If \a symbol is specified it will be used as the currency
+ symbol.
+
+ \sa Locale::currencySymbol()
+*/
+
+/*!
+ \qmlmethod string Number::fromLocaleString(locale,number)
+
+ Returns a Number by parsing \a number using the conventions of the supplied \a locale.
+
+ If \a locale is not supplied the default locale will be used.
+
+ For example, using the German locale:
+ \code
+ var german = Qt.locale("de_DE");
+ var d;
+ d = Number.fromLocaleString(german, "1234,56) // d == 1234.56
+ d = Number.fromLocaleString(german, "1.234,56") // d == 1234.56
+ d = Number.fromLocaleString(german, "1234.56") // throws exception
+ d = Number.fromLocaleString(german, "1.234") // d == 1234.0
+ \endcode
+*/
+
diff --git a/doc/src/qtquick1/declarativeui.qdoc b/doc/src/qtquick1/declarativeui.qdoc
index 41dedecb8e..e1d5755b47 100644
--- a/doc/src/qtquick1/declarativeui.qdoc
+++ b/doc/src/qtquick1/declarativeui.qdoc
@@ -77,7 +77,7 @@ Qt applications.
\o \l{Integrating QML Code with Existing Qt UI Code}
\o \l{Dynamic Object Management in QML}{Dynamic Object Management}
\o \l{Network Transparency}{Loading Resources in QML}
-\o \l{QML Internationalization}{Internationalization}
+\o \l{QML Internationalization}{Qt Quick 1 Internationalization}
\endlist
\section1 QML Add-Ons
diff --git a/doc/src/qtquick1/qdeclarativei18n.qdoc b/doc/src/qtquick1/qdeclarativei18n.qdoc
index 76892173ff..e985abe61d 100644
--- a/doc/src/qtquick1/qdeclarativei18n.qdoc
+++ b/doc/src/qtquick1/qdeclarativei18n.qdoc
@@ -32,7 +32,7 @@
\contentspage QML Features
\previouspage {Network Transparency}{Loading Resources in QML}
\nextpage {QML Features}
-\title QML Internationalization
+\title Qt Quick 1 Internationalization
Strings in QML can be marked for translation using the qsTr(), qsTranslate(),
diff --git a/examples/declarative/locale/locale.qml b/examples/declarative/locale/locale.qml
new file mode 100644
index 0000000000..4d56ecff0b
--- /dev/null
+++ b/examples/declarative/locale/locale.qml
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ width: 320
+ height: 480
+ color: "lightgray"
+
+ property string locale: view.currentItem.locale
+
+ Text {
+ id: title
+ text: "Select locale:"
+ }
+
+ Rectangle {
+ id: chooser
+ anchors.top: title.bottom
+ anchors.topMargin: 5
+ width: parent.width-10
+ x: 5
+ height: parent.height/2 - 10
+ color: "#40300030"
+ ListView {
+ id: view
+ clip: true
+ focus: true
+ anchors.fill: parent
+ model: [
+ "en_US",
+ "en_GB",
+ "fi_FI",
+ "de_DE",
+ "ar_SA",
+ "hi_IN",
+ "zh_CN",
+ "th_TH",
+ "fr_FR",
+ "nb_NO",
+ "sv_SE"
+ ]
+ delegate: Text {
+ property string locale: modelData
+ height: 30
+ width: view.width
+ text: Qt.locale(modelData).name + " ("+ Qt.locale(modelData).nativeCountryName + "/" + Qt.locale(modelData).nativeLanguageName + ")"
+ MouseArea {
+ anchors.fill: parent
+ onClicked: view.currentIndex = index
+ }
+ }
+ highlight: Rectangle {
+ height: 30
+ color: "#60300030"
+ }
+ }
+ }
+
+ Rectangle {
+ color: "white"
+ anchors.top: chooser.bottom
+ anchors.topMargin: 5
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 5
+ x: 5; width: parent.width - 10
+
+ Column {
+ anchors.fill: parent
+ spacing: 5
+ Text {
+ property var date: new Date()
+ text: "Date: " + date.toLocaleDateString(Qt.locale(root.locale))
+ }
+ Text {
+ property var date: new Date()
+ text: "Time: " + date.toLocaleTimeString(Qt.locale(root.locale))
+ }
+ Text {
+ property var dow: Qt.locale(root.locale).firstDayOfWeek
+ text: "First day of week: " + Qt.locale(root.locale).standaloneDayName(dow)
+ }
+ Text {
+ property var num: 10023823
+ text: "Number: " + num.toLocaleString(Qt.locale(root.locale))
+ }
+ Text {
+ property var num: 10023823
+ text: "Currency: " + num.toLocaleCurrencyString(Qt.locale(root.locale))
+ }
+ }
+ }
+}
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 1323669fc7..ef638b4e44 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -85,6 +85,7 @@
#include <private/qdeclarativeutilmodule_p.h>
#include <private/qquickitemsmodule_p.h>
#include <private/qquickparticlesmodule_p.h>
+#include <private/qdeclarativelocale_p.h>
#ifdef Q_OS_WIN // for %APPDATA%
#include <qt_windows.h>
@@ -174,6 +175,7 @@ void QDeclarativeEnginePrivate::defineModule()
{
registerBaseTypes("QtQuick", 2, 0);
qmlRegisterType<QDeclarativeBinding>();
+ qmlRegisterUncreatableType<QDeclarativeLocale>("QtQuick",2,0,"Locale",QDeclarativeEngine::tr("Locale cannot be instantiated. Use Qt.locale()"));
}
/*!
diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h
index a678a4588c..14ee62872d 100644
--- a/src/declarative/qml/qdeclarativeengine_p.h
+++ b/src/declarative/qml/qdeclarativeengine_p.h
@@ -81,6 +81,7 @@
#include <private/qobject_p.h>
#include <private/qv8engine_p.h>
+#include <private/qjsengine_p.h>
QT_BEGIN_NAMESPACE
@@ -119,7 +120,7 @@ public:
QDeclarativeJavaScriptExpressionGuard *next;
};
-class Q_DECLARATIVE_EXPORT QDeclarativeEnginePrivate : public QObjectPrivate
+class Q_DECLARATIVE_EXPORT QDeclarativeEnginePrivate : public QJSEnginePrivate
{
Q_DECLARE_PUBLIC(QDeclarativeEngine)
public:
diff --git a/src/declarative/qml/qdeclarativelocale.cpp b/src/declarative/qml/qdeclarativelocale.cpp
new file mode 100644
index 0000000000..bbde2d801c
--- /dev/null
+++ b/src/declarative/qml/qdeclarativelocale.cpp
@@ -0,0 +1,1095 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativelocale_p.h"
+#include "qdeclarativeengine_p.h"
+#include <private/qdeclarativecontext_p.h>
+#include <private/qjsconverter_impl_p.h>
+#include <QtCore/qnumeric.h>
+#include <QtCore/qdatetime.h>
+
+#include <private/qlocale_p.h>
+#include <private/qlocale_data_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QV8LocaleDataResource : public QV8ObjectResource
+{
+ V8_RESOURCE_TYPE(LocaleDataType)
+public:
+ QV8LocaleDataResource(QV8Engine *e) : QV8ObjectResource(e) {}
+ QLocale locale;
+};
+
+#define GET_LOCALE_DATA_RESOURCE(OBJECT) \
+QV8LocaleDataResource *r = v8_resource_cast<QV8LocaleDataResource>(OBJECT); \
+if (!r) \
+ V8THROW_ERROR("Not a valid Locale object")
+
+static bool isLocaleObject(v8::Handle<v8::Value> val)
+{
+ if (!val->IsObject())
+ return false;
+
+ v8::Handle<v8::Object> localeObj = val->ToObject();
+ return localeObj->Has(v8::String::New("nativeLanguageName")); //XXX detect locale object properly
+}
+
+//--------------
+// Date extension
+
+static const char *dateToLocaleStringFunction =
+ "(function(toLocaleStringFunc) { "
+ " var orig_toLocaleString;"
+ " orig_toLocaleString = Date.prototype.toLocaleString;"
+ " Date.prototype.toLocaleString = (function() {"
+ " var val = toLocaleStringFunc.apply(this, arguments);"
+ " if (val == undefined) val = orig_toLocaleString.call(this);"
+ " return val;"
+ " })"
+ "})";
+
+static const char *dateToLocaleTimeStringFunction =
+ "(function(toLocaleTimeStringFunc) { "
+ " var orig_toLocaleTimeString;"
+ " orig_toLocaleTimeString = Date.prototype.toLocaleTimeString;"
+ " Date.prototype.toLocaleTimeString = (function() {"
+ " var val = toLocaleTimeStringFunc.apply(this, arguments);"
+ " if (val == undefined) val = orig_toLocaleTimeString.call(this);"
+ " return val;"
+ " })"
+ "})";
+
+static const char *dateToLocaleDateStringFunction =
+ "(function(toLocaleDateStringFunc) { "
+ " var orig_toLocaleDateString;"
+ " orig_toLocaleDateString = Date.prototype.toLocaleDateString;"
+ " Date.prototype.toLocaleDateString = (function() {"
+ " var val = toLocaleDateStringFunc.apply(this, arguments);"
+ " if (val == undefined) val = orig_toLocaleDateString.call(this);"
+ " return val;"
+ " })"
+ "})";
+
+
+static const char *dateFromLocaleStringFunction =
+ "(function(fromLocaleStringFunc) { "
+ " Date.fromLocaleString = (function() {"
+ " return fromLocaleStringFunc.apply(null, arguments);"
+ " })"
+ "})";
+
+static const char *dateFromLocaleTimeStringFunction =
+ "(function(fromLocaleTimeStringFunc) { "
+ " Date.fromLocaleTimeString = (function() {"
+ " return fromLocaleTimeStringFunc.apply(null, arguments);"
+ " })"
+ "})";
+
+static const char *dateFromLocaleDateStringFunction =
+ "(function(fromLocaleDateStringFunc) { "
+ " Date.fromLocaleDateString = (function() {"
+ " return fromLocaleDateStringFunc.apply(null, arguments);"
+ " })"
+ "})";
+
+
+static void registerFunction(QV8Engine *engine, const char *script, v8::InvocationCallback func)
+{
+ v8::Local<v8::Script> registerScript = v8::Script::New(v8::String::New(script), 0, 0, v8::Handle<v8::String>(), v8::Script::NativeMode);
+ v8::Local<v8::Value> result = registerScript->Run();
+ Q_ASSERT(result->IsFunction());
+ v8::Local<v8::Function> registerFunc = v8::Local<v8::Function>::Cast(result);
+ v8::Handle<v8::Value> args = V8FUNCTION(func, engine);
+ registerFunc->Call(v8::Local<v8::Object>::Cast(registerFunc), 1, &args);
+}
+
+void QDeclarativeDateExtension::registerExtension(QV8Engine *engine)
+{
+ registerFunction(engine, dateToLocaleStringFunction, toLocaleString);
+ registerFunction(engine, dateToLocaleTimeStringFunction, toLocaleTimeString);
+ registerFunction(engine, dateToLocaleDateStringFunction, toLocaleDateString);
+ registerFunction(engine, dateFromLocaleStringFunction, fromLocaleString);
+ registerFunction(engine, dateFromLocaleTimeStringFunction, fromLocaleTimeString);
+ registerFunction(engine, dateFromLocaleDateStringFunction, fromLocaleDateString);
+}
+
+v8::Handle<v8::Value> QDeclarativeDateExtension::toLocaleString(const v8::Arguments& args)
+{
+ if (args.Length() > 2)
+ return v8::Undefined();
+
+ if (!args.This()->IsDate())
+ return v8::Undefined();
+
+ QDateTime dt = QV8Engine::qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(args.This())->NumberValue());
+
+ if (args.Length() == 0) {
+ // Use QLocale for standard toLocaleString() function
+ QLocale locale;
+ return QJSConverter::toString(locale.toString(dt));
+ }
+
+ if (!isLocaleObject(args[0]))
+ return v8::Undefined(); // Use the default Date toLocaleString()
+
+ GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
+
+ QLocale::FormatType enumFormat = QLocale::LongFormat;
+ QString formattedDt;
+ if (args.Length() == 2) {
+ if (args[1]->IsString()) {
+ QString format = r->engine->toVariant(args[1], -1).toString();
+ formattedDt = r->locale.toString(dt, format);
+ } else if (args[1]->IsNumber()) {
+ quint32 intFormat = args[1]->ToNumber()->Value();
+ QLocale::FormatType format = QLocale::FormatType(intFormat);
+ formattedDt = r->locale.toString(dt, format);
+ } else {
+ V8THROW_ERROR("Locale: Date.toLocaleString(): Invalid datetime format");
+ }
+ } else {
+ formattedDt = r->locale.toString(dt, enumFormat);
+ }
+
+ return r->engine->toString(formattedDt);
+}
+
+v8::Handle<v8::Value> QDeclarativeDateExtension::toLocaleTimeString(const v8::Arguments& args)
+{
+ if (args.Length() > 2)
+ return v8::Undefined();
+
+ if (!args.This()->IsDate())
+ return v8::Undefined();
+
+ QDateTime dt = QV8Engine::qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(args.This())->NumberValue());
+ QTime time = dt.time();
+
+ if (args.Length() == 0) {
+ // Use QLocale for standard toLocaleString() function
+ QLocale locale;
+ return QJSConverter::toString(locale.toString(time));
+ }
+
+ if (!isLocaleObject(args[0]))
+ return v8::Undefined(); // Use the default Date toLocaleTimeString()
+
+ GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
+
+ QLocale::FormatType enumFormat = QLocale::LongFormat;
+ QString formattedTime;
+ if (args.Length() == 2) {
+ if (args[1]->IsString()) {
+ QString format = r->engine->toVariant(args[1], -1).toString();
+ formattedTime = r->locale.toString(time, format);
+ } else if (args[1]->IsNumber()) {
+ quint32 intFormat = args[1]->ToNumber()->Value();
+ QLocale::FormatType format = QLocale::FormatType(intFormat);
+ formattedTime = r->locale.toString(time, format);
+ } else {
+ V8THROW_ERROR("Locale: Date.toLocaleTimeString(): Invalid time format");
+ }
+ } else {
+ formattedTime = r->locale.toString(time, enumFormat);
+ }
+
+ return r->engine->toString(formattedTime);
+}
+
+v8::Handle<v8::Value> QDeclarativeDateExtension::toLocaleDateString(const v8::Arguments& args)
+{
+ if (args.Length() > 2)
+ return v8::Undefined();
+
+ if (!args.This()->IsDate())
+ return v8::Undefined();
+
+ QDateTime dt = QV8Engine::qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(args.This())->NumberValue());
+ QDate date = dt.date();
+
+ if (args.Length() == 0) {
+ // Use QLocale for standard toLocaleString() function
+ QLocale locale;
+ return QJSConverter::toString(locale.toString(date));
+ }
+
+ if (!isLocaleObject(args[0]))
+ return v8::Undefined(); // Use the default Date toLocaleDateString()
+
+ GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
+
+ QLocale::FormatType enumFormat = QLocale::LongFormat;
+ QString formattedDate;
+ if (args.Length() == 2) {
+ if (args[1]->IsString()) {
+ QString format = r->engine->toVariant(args[1], -1).toString();
+ formattedDate = r->locale.toString(date, format);
+ } else if (args[1]->IsNumber()) {
+ quint32 intFormat = args[1]->ToNumber()->Value();
+ QLocale::FormatType format = QLocale::FormatType(intFormat);
+ formattedDate = r->locale.toString(date, format);
+ } else {
+ V8THROW_ERROR("Locale: Date.loLocaleDateString(): Invalid date format");
+ }
+ } else {
+ formattedDate = r->locale.toString(date, enumFormat);
+ }
+
+ return r->engine->toString(formattedDate);
+}
+
+v8::Handle<v8::Value> QDeclarativeDateExtension::fromLocaleString(const v8::Arguments& args)
+{
+ if (args.Length() == 1 && args[0]->IsString()) {
+ QLocale locale;
+ QString dateString = QJSConverter::toString(args[0]->ToString());
+ QDateTime dt = locale.toDateTime(dateString);
+ return QJSConverter::toDateTime(dt);
+ }
+
+ if (args.Length() < 1 || args.Length() > 3 || !isLocaleObject(args[0]))
+ V8THROW_ERROR("Locale: Date.fromLocaleString(): Invalid arguments");
+
+ GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
+
+ QLocale::FormatType enumFormat = QLocale::LongFormat;
+ QDateTime dt;
+ QString dateString = r->engine->toString(args[1]->ToString());
+ if (args.Length() == 3) {
+ if (args[2]->IsString()) {
+ QString format = r->engine->toString(args[2]->ToString());
+ dt = r->locale.toDateTime(dateString, format);
+ } else if (args[2]->IsNumber()) {
+ quint32 intFormat = args[2]->ToNumber()->Value();
+ QLocale::FormatType format = QLocale::FormatType(intFormat);
+ dt = r->locale.toDateTime(dateString, format);
+ } else {
+ V8THROW_ERROR("Locale: Date.fromLocaleString(): Invalid datetime format");
+ }
+ } else {
+ dt = r->locale.toDateTime(dateString, enumFormat);
+ }
+
+ return QJSConverter::toDateTime(dt);
+}
+
+v8::Handle<v8::Value> QDeclarativeDateExtension::fromLocaleTimeString(const v8::Arguments& args)
+{
+ if (args.Length() == 1 && args[0]->IsString()) {
+ QLocale locale;
+ QString timeString = QJSConverter::toString(args[0]->ToString());
+ QTime time = locale.toTime(timeString);
+ QDateTime dt = QDateTime::currentDateTime();
+ dt.setTime(time);
+ return QJSConverter::toDateTime(dt);
+ }
+
+ if (args.Length() < 1 || args.Length() > 3 || !isLocaleObject(args[0]))
+ V8THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid arguments");
+
+ GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
+
+ QLocale::FormatType enumFormat = QLocale::LongFormat;
+ QTime tm;
+ QString dateString = r->engine->toString(args[1]->ToString());
+ if (args.Length() == 3) {
+ if (args[2]->IsString()) {
+ QString format = r->engine->toString(args[2]->ToString());
+ tm = r->locale.toTime(dateString, format);
+ } else if (args[2]->IsNumber()) {
+ quint32 intFormat = args[2]->ToNumber()->Value();
+ QLocale::FormatType format = QLocale::FormatType(intFormat);
+ tm = r->locale.toTime(dateString, format);
+ } else {
+ V8THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid datetime format");
+ }
+ } else {
+ tm = r->locale.toTime(dateString, enumFormat);
+ }
+
+ QDateTime dt = QDateTime::currentDateTime();
+ dt.setTime(tm);
+
+ return QJSConverter::toDateTime(dt);
+}
+
+v8::Handle<v8::Value> QDeclarativeDateExtension::fromLocaleDateString(const v8::Arguments& args)
+{
+ if (args.Length() == 1 && args[0]->IsString()) {
+ QLocale locale;
+ QString dateString = QJSConverter::toString(args[0]->ToString());
+ QDate date = locale.toDate(dateString);
+ return QJSConverter::toDateTime(QDateTime(date));
+ }
+
+ if (args.Length() < 1 || args.Length() > 3 || !isLocaleObject(args[0]))
+ V8THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid arguments");
+
+ GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
+
+ QLocale::FormatType enumFormat = QLocale::LongFormat;
+ QDate dt;
+ QString dateString = r->engine->toString(args[1]->ToString());
+ if (args.Length() == 3) {
+ if (args[2]->IsString()) {
+ QString format = r->engine->toString(args[2]->ToString());
+ dt = r->locale.toDate(dateString, format);
+ } else if (args[2]->IsNumber()) {
+ quint32 intFormat = args[2]->ToNumber()->Value();
+ QLocale::FormatType format = QLocale::FormatType(intFormat);
+ dt = r->locale.toDate(dateString, format);
+ } else {
+ V8THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid datetime format");
+ }
+ } else {
+ dt = r->locale.toDate(dateString, enumFormat);
+ }
+
+ return QJSConverter::toDateTime(QDateTime(dt));
+}
+
+//-----------------
+// Number extension
+
+static const char *numberToLocaleStringFunction =
+ "(function(toLocaleStringFunc) { "
+ " var orig_toLocaleString;"
+ " orig_toLocaleString = Number.prototype.toLocaleString;"
+ " Number.prototype.toLocaleString = (function() {"
+ " var val = toLocaleStringFunc.apply(this, arguments);"
+ " if (val == undefined) val = orig_toLocaleString.call(this);"
+ " return val;"
+ " })"
+ "})";
+
+static const char *numberToLocaleCurrencyStringFunction =
+ "(function(toLocaleCurrencyStringFunc) { "
+ " Number.prototype.toLocaleCurrencyString = (function() {"
+ " return toLocaleCurrencyStringFunc.apply(this, arguments);"
+ " })"
+ "})";
+
+static const char *numberFromLocaleStringFunction =
+ "(function(fromLocaleStringFunc) { "
+ " Number.fromLocaleString = (function() {"
+ " return fromLocaleStringFunc.apply(null, arguments);"
+ " })"
+ "})";
+
+
+void QDeclarativeNumberExtension::registerExtension(QV8Engine *engine)
+{
+ registerFunction(engine, numberToLocaleStringFunction, toLocaleString);
+ registerFunction(engine, numberToLocaleCurrencyStringFunction, toLocaleCurrencyString);
+ registerFunction(engine, numberFromLocaleStringFunction, fromLocaleString);
+}
+
+v8::Handle<v8::Value> QDeclarativeNumberExtension::toLocaleString(const v8::Arguments& args)
+{
+ if (args.Length() > 3)
+ V8THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
+
+ double number = args.This()->ToNumber()->Value();
+
+ if (args.Length() == 0) {
+ // Use QLocale for standard toLocaleString() function
+ QLocale locale;
+ return QJSConverter::toString(locale.toString(number));
+ }
+
+ if (!isLocaleObject(args[0]))
+ return v8::Undefined(); // Use the default Number toLocaleString()
+
+ GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
+
+ uint16_t format = 'f';
+ if (args.Length() > 1) {
+ if (!args[1]->IsString())
+ V8THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
+ v8::Local<v8::String> fs = args[1]->ToString();
+ if (!fs.IsEmpty() && fs->Length())
+ format = fs->GetCharacter(0);
+ }
+ int prec = 2;
+ if (args.Length() > 2) {
+ if (!args[2]->IsNumber())
+ V8THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
+ prec = args[2]->IntegerValue();
+ }
+
+ return r->engine->toString(r->locale.toString(number, (char)format, prec));
+}
+
+v8::Handle<v8::Value> QDeclarativeNumberExtension::toLocaleCurrencyString(const v8::Arguments& args)
+{
+ if (args.Length() > 2)
+ V8THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
+
+ double number = args.This()->ToNumber()->Value();
+
+ if (args.Length() == 0) {
+ // Use QLocale for standard toLocaleString() function
+ QLocale locale;
+ return QJSConverter::toString(locale.toString(number));
+ }
+
+ if (!isLocaleObject(args[0]))
+ V8THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
+
+ GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
+
+ QString symbol;
+ if (args.Length() > 1) {
+ if (!args[1]->IsString())
+ V8THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
+ symbol = r->engine->toString(args[1]->ToString());
+ }
+
+ return r->engine->toString(r->locale.toCurrencyString(number, symbol));
+}
+
+v8::Handle<v8::Value> QDeclarativeNumberExtension::fromLocaleString(const v8::Arguments& args)
+{
+ if (args.Length() < 1 || args.Length() > 2)
+ V8THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
+
+ int numberIdx = 0;
+ QLocale locale;
+
+ if (args.Length() == 2) {
+ if (!isLocaleObject(args[0]))
+ V8THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
+
+ GET_LOCALE_DATA_RESOURCE(args[0]->ToObject());
+ locale = r->locale;
+
+ numberIdx = 1;
+ }
+
+ v8::Local<v8::String> ns = args[numberIdx]->ToString();
+ if (ns.IsEmpty() || ns->Length() == 0)
+ return v8::Number::New(Q_QNAN);
+
+ bool ok = false;
+ double val = locale.toDouble(QJSConverter::toString(ns), &ok);
+
+ if (!ok)
+ V8THROW_ERROR("Locale: Number.fromLocaleString(): Invalid format")
+
+ return v8::Number::New(val);
+}
+
+//--------------
+// Locale object
+
+static v8::Handle<v8::Value> locale_get_firstDayOfWeek(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ GET_LOCALE_DATA_RESOURCE(info.This());
+ return v8::Integer::New(r->locale.firstDayOfWeek());
+}
+
+static v8::Handle<v8::Value> locale_get_measurementSystem(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ GET_LOCALE_DATA_RESOURCE(info.This());
+ return v8::Integer::New(r->locale.measurementSystem());
+}
+
+static v8::Handle<v8::Value> locale_get_textDirection(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ GET_LOCALE_DATA_RESOURCE(info.This());
+ return v8::Integer::New(r->locale.textDirection());
+}
+
+static v8::Handle<v8::Value> locale_get_weekDays(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ GET_LOCALE_DATA_RESOURCE(info.This());
+
+ QList<Qt::DayOfWeek> days = r->locale.weekdays();
+
+ v8::Handle<v8::Array> result = v8::Array::New(days.size());
+ for (int i = 0; i < days.size(); ++i) {
+ int day = days.at(i);
+ if (day == 7) // JS Date days in range 0(Sunday) to 6(Saturday)
+ day = 0;
+ result->Set(i, v8::Integer::New(day));
+ }
+
+ return result;
+}
+
+static v8::Handle<v8::Value> locale_currencySymbol(const v8::Arguments &args)
+{
+ GET_LOCALE_DATA_RESOURCE(args.This());
+
+ if (args.Length() > 1)
+ V8THROW_ERROR("Locale: currencySymbol(): Invalid arguments");
+
+ QLocale::CurrencySymbolFormat format = QLocale::CurrencySymbol;
+ if (args.Length() == 1) {
+ quint32 intFormat = args[0]->ToNumber()->Value();
+ format = QLocale::CurrencySymbolFormat(intFormat);
+ }
+
+ return r->engine->toString(r->locale.currencySymbol(format));
+}
+
+#define LOCALE_FORMAT(FUNC) \
+static v8::Handle<v8::Value> locale_ ##FUNC (const v8::Arguments &args) { \
+ GET_LOCALE_DATA_RESOURCE(args.This());\
+ if (args.Length() > 1) \
+ V8THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \
+ QLocale::FormatType format = QLocale::LongFormat;\
+ if (args.Length() == 1) { \
+ quint32 intFormat = args[0]->Uint32Value(); \
+ format = QLocale::FormatType(intFormat); \
+ } \
+ return r->engine->toString(r->locale. FUNC (format)); \
+}
+
+LOCALE_FORMAT(dateTimeFormat)
+LOCALE_FORMAT(timeFormat)
+LOCALE_FORMAT(dateFormat)
+
+// +1 added to idx because JS is 0-based, whereas QLocale months begin at 1.
+#define LOCALE_FORMATTED_MONTHNAME(VARIABLE) \
+static v8::Handle<v8::Value> locale_ ## VARIABLE (const v8::Arguments &args) {\
+ GET_LOCALE_DATA_RESOURCE(args.This()); \
+ if (args.Length() < 1 || args.Length() > 2) \
+ V8THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
+ QLocale::FormatType enumFormat = QLocale::LongFormat; \
+ int idx = args[0]->IntegerValue() + 1; \
+ if (idx < 1 || idx > 12) \
+ V8THROW_ERROR("Locale: Invalid month"); \
+ QString name; \
+ if (args.Length() == 2) { \
+ if (args[1]->IsNumber()) { \
+ quint32 intFormat = args[1]->IntegerValue(); \
+ QLocale::FormatType format = QLocale::FormatType(intFormat); \
+ name = r->locale. VARIABLE(idx, format); \
+ } else { \
+ V8THROW_ERROR("Locale: Invalid datetime format"); \
+ } \
+ } else { \
+ name = r->locale. VARIABLE(idx, enumFormat); \
+ } \
+ return r->engine->toString(name); \
+}
+
+// 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date
+#define LOCALE_FORMATTED_DAYNAME(VARIABLE) \
+static v8::Handle<v8::Value> locale_ ## VARIABLE (const v8::Arguments &args) {\
+ GET_LOCALE_DATA_RESOURCE(args.This()); \
+ if (args.Length() < 1 || args.Length() > 2) \
+ V8THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
+ QLocale::FormatType enumFormat = QLocale::LongFormat; \
+ int idx = args[0]->IntegerValue(); \
+ if (idx < 0 || idx > 7) \
+ V8THROW_ERROR("Locale: Invalid day"); \
+ if (idx == 0) idx = 7; \
+ QString name; \
+ if (args.Length() == 2) { \
+ if (args[1]->IsNumber()) { \
+ quint32 intFormat = args[1]->ToNumber()->Value(); \
+ QLocale::FormatType format = QLocale::FormatType(intFormat); \
+ name = r->locale. VARIABLE(idx, format); \
+ } else { \
+ V8THROW_ERROR("Locale: Invalid datetime format"); \
+ } \
+ } else { \
+ name = r->locale. VARIABLE(idx, enumFormat); \
+ } \
+ return r->engine->toString(name); \
+}
+
+
+#define LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(FT, VARIABLE, ENGINE) \
+ FT->PrototypeTemplate()->Set(v8::String::New( #VARIABLE ), V8FUNCTION(locale_ ## VARIABLE, ENGINE));
+
+LOCALE_FORMATTED_MONTHNAME(monthName)
+LOCALE_FORMATTED_MONTHNAME(standaloneMonthName)
+LOCALE_FORMATTED_DAYNAME(dayName)
+LOCALE_FORMATTED_DAYNAME(standaloneDayName)
+
+#define LOCALE_STRING_PROPERTY(VARIABLE) static v8::Handle<v8::Value> locale_get_ ## VARIABLE (v8::Local<v8::String>, const v8::AccessorInfo &info) \
+{ \
+ GET_LOCALE_DATA_RESOURCE(info.This()); \
+ return r->engine->toString(r->locale. VARIABLE());\
+}
+
+#define LOCALE_REGISTER_STRING_ACCESSOR(FT, VARIABLE) \
+ FT ->PrototypeTemplate()->SetAccessor( v8::String::New( #VARIABLE ), locale_get_ ## VARIABLE )
+
+
+LOCALE_STRING_PROPERTY(name)
+LOCALE_STRING_PROPERTY(nativeLanguageName)
+LOCALE_STRING_PROPERTY(nativeCountryName)
+LOCALE_STRING_PROPERTY(decimalPoint)
+LOCALE_STRING_PROPERTY(groupSeparator)
+LOCALE_STRING_PROPERTY(percent)
+LOCALE_STRING_PROPERTY(zeroDigit)
+LOCALE_STRING_PROPERTY(negativeSign)
+LOCALE_STRING_PROPERTY(positiveSign)
+LOCALE_STRING_PROPERTY(exponential)
+LOCALE_STRING_PROPERTY(amText)
+LOCALE_STRING_PROPERTY(pmText)
+
+class QV8LocaleDataDeletable : public QV8Engine::Deletable
+{
+public:
+ QV8LocaleDataDeletable(QV8Engine *engine);
+ ~QV8LocaleDataDeletable();
+
+ v8::Persistent<v8::Function> constructor;
+};
+
+QV8LocaleDataDeletable::QV8LocaleDataDeletable(QV8Engine *engine)
+{
+ v8::HandleScope handle_scope;
+ v8::Context::Scope scope(engine->context());
+
+ v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
+ ft->InstanceTemplate()->SetHasExternalResource(true);
+
+ LOCALE_REGISTER_STRING_ACCESSOR(ft, name);
+ LOCALE_REGISTER_STRING_ACCESSOR(ft, nativeLanguageName);
+ LOCALE_REGISTER_STRING_ACCESSOR(ft, nativeCountryName);
+ LOCALE_REGISTER_STRING_ACCESSOR(ft, decimalPoint);
+ LOCALE_REGISTER_STRING_ACCESSOR(ft, groupSeparator);
+ LOCALE_REGISTER_STRING_ACCESSOR(ft, percent);
+ LOCALE_REGISTER_STRING_ACCESSOR(ft, zeroDigit);
+ LOCALE_REGISTER_STRING_ACCESSOR(ft, negativeSign);
+ LOCALE_REGISTER_STRING_ACCESSOR(ft, positiveSign);
+ LOCALE_REGISTER_STRING_ACCESSOR(ft, exponential);
+ LOCALE_REGISTER_STRING_ACCESSOR(ft, amText);
+ LOCALE_REGISTER_STRING_ACCESSOR(ft, pmText);
+
+ ft->PrototypeTemplate()->Set(v8::String::New("currencySymbol"), V8FUNCTION(locale_currencySymbol, engine));
+
+ ft->PrototypeTemplate()->Set(v8::String::New("dateTimeFormat"), V8FUNCTION(locale_dateTimeFormat, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("dateFormat"), V8FUNCTION(locale_dateFormat, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("timeFormat"), V8FUNCTION(locale_timeFormat, engine));
+
+ LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(ft, monthName, engine);
+ LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(ft, standaloneMonthName, engine);
+ LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(ft, dayName, engine);
+ LOCALE_REGISTER_FORMATTED_NAME_FUNCTION(ft, standaloneDayName, engine);
+
+ ft->PrototypeTemplate()->SetAccessor(v8::String::New("firstDayOfWeek"), locale_get_firstDayOfWeek);
+ ft->PrototypeTemplate()->SetAccessor(v8::String::New("weekDays"), locale_get_weekDays);
+ ft->PrototypeTemplate()->SetAccessor(v8::String::New("measurementSystem"), locale_get_measurementSystem);
+ ft->PrototypeTemplate()->SetAccessor(v8::String::New("textDirection"), locale_get_textDirection);
+
+ constructor = qPersistentNew(ft->GetFunction());
+}
+
+QV8LocaleDataDeletable::~QV8LocaleDataDeletable()
+{
+ qPersistentDispose(constructor);
+}
+
+V8_DEFINE_EXTENSION(QV8LocaleDataDeletable, localeV8Data);
+
+class QV8LocaleData {
+public:
+ QV8LocaleData(QV8Engine*,const QLocale &);
+ ~QV8LocaleData();
+ QDeclarativeV8Handle v8Value();
+private:
+ v8::Persistent<v8::Object> m_v8Value;
+};
+
+QV8LocaleData::QV8LocaleData(QV8Engine *engine, const QLocale &locale)
+{
+ if (!engine)
+ return;
+
+ QV8LocaleDataDeletable *d = localeV8Data(engine);
+ m_v8Value = qPersistentNew(d->constructor->NewInstance());
+ QV8LocaleDataResource *r = new QV8LocaleDataResource(engine);
+ r->locale = locale;
+ m_v8Value->SetExternalResource(r);
+}
+
+QV8LocaleData::~QV8LocaleData()
+{
+ qPersistentDispose(m_v8Value);
+}
+
+QDeclarativeV8Handle QV8LocaleData::v8Value()
+{
+ return QDeclarativeV8Handle::fromHandle(m_v8Value);
+}
+
+/*!
+ \qmlclass Locale QDeclarativeLocale
+ \inqmlmodule QtQuick 2
+ \brief The Locale object provides locale specific properties and formatted data.
+
+ The Locale object is created via the \l{QML:Qt::locale()}{Qt.locale()} function. It cannot be created
+ directly.
+
+ The \l{QML:Qt::locale()}{Qt.locale()} function returns a JS Locale object representing the
+ locale with the specified name, which has the format
+ "language[_territory][.codeset][@modifier]" or "C".
+
+ Locale supports the concept of a default locale, which is
+ determined from the system's locale settings at application
+ startup. If no parameter is passed to Qt.locale() the default
+ locale object is returned.
+
+ The Locale object provides a number of functions and properties
+ providing data for the specified locale.
+
+ The Locale object may also be passed to the \l Date and \l Number toLocaleString()
+ and fromLocaleString() methods in order to convert to/from strings using
+ the specified locale.
+
+ This example shows the current date formatted for the German locale:
+
+ \code
+ import QtQuick 2.0
+
+ Text {
+ text: "The date is: " + Date().toLocaleString(Qt.locale("de_DE"))
+ }
+ \endcode
+
+ The following example displays the specified number
+ in the correct format for the default locale:
+
+ \code
+ import QtQuick 2.0
+
+ Text {
+ text: "The value is: " + Number(23443.34).toLocaleString(Qt.locale())
+ }
+ \endcode
+
+ QtQuick Locale's data is based on Common Locale Data Repository v1.8.1.
+
+ The double-to-string and string-to-double conversion functions are
+ covered by the following licenses:
+
+ \legalese
+ Copyright (c) 1991 by AT&T.
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose without fee is hereby granted, provided that this entire notice
+ is included in all copies of any software which is or includes a copy
+ or modification of this software and in all copies of the supporting
+ documentation for such software.
+
+ THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+
+ This product includes software developed by the University of
+ California, Berkeley and its contributors.
+
+ \sa {QtQuick2::Date}{Date} {QtQuick2::Number}{Number}
+*/
+
+QDeclarativeLocale::QDeclarativeLocale()
+{
+}
+
+QDeclarativeLocale::~QDeclarativeLocale()
+{
+}
+
+v8::Handle<v8::Value> QDeclarativeLocale::locale(QV8Engine *v8engine, const QString &locale)
+{
+ QV8LocaleDataDeletable *d = localeV8Data(v8engine);
+ v8::Local<v8::Object> v8Value = d->constructor->NewInstance();
+ QV8LocaleDataResource *r = new QV8LocaleDataResource(v8engine);
+ r->locale = QLocale(locale);
+ v8Value->SetExternalResource(r);
+
+ return v8Value;
+}
+
+/*!
+ \enum QtQuick2::Locale::FormatType
+
+ This enumeration describes the types of format that can be used when
+ converting Date objects to strings.
+
+ \value LongFormat The long version of day and month names; for
+ example, returning "January" as a month name.
+
+ \value ShortFormat The short version of day and month names; for
+ example, returning "Jan" as a month name.
+
+ \value NarrowFormat A special version of day and month names for
+ use when space is limited; for example, returning "J" as a month
+ name. Note that the narrow format might contain the same text for
+ different months and days or it can even be an empty string if the
+ locale doesn't support narrow names, so you should avoid using it
+ for date formatting. Also, for the system locale this format is
+ the same as ShortFormat.
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Locale::name
+
+ Holds the language and country of this locale as a
+ string of the form "language_country", where
+ language is a lowercase, two-letter ISO 639 language code,
+ and country is an uppercase, two- or three-letter ISO 3166 country code.
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Locale::decimalPoint
+
+ Holds the decimal point character of this locale.
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Locale::groupSeparator
+
+ Holds the group separator character of this locale.
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Locale::percent
+
+ Holds the percent character of this locale.
+*/
+
+
+/*!
+ \qmlproperty string QtQuick2::Locale::zeroDigit
+
+ Holds Returns the zero digit character of this locale.
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Locale::negativeSign
+
+ Holds the negative sign character of this locale.
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Locale::positiveSign
+
+ Holds the positive sign character of this locale.
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Locale::exponential
+
+ Holds the exponential character of this locale.
+*/
+
+/*!
+ \qmlmethod string QtQuick2::Locale::dateTimeFormat(type)
+
+ Returns the date time format used for the current locale.
+ \a type specifies the FormatType to return.
+
+ \sa {QtQuick2::Date}{Date}
+*/
+
+/*!
+ \qmlmethod string QtQuick2::Locale::dateFormat(type)
+
+ Returns the date format used for the current locale.
+ \a type specifies the FormatType to return.
+
+ \sa {QtQuick2::Date}{Date}
+*/
+
+/*!
+ \qmlmethod string QtQuick2::Locale::timeFormat(type)
+
+ Returns the time format used for the current locale.
+ \a type specifies the FormatType to return.
+
+ \sa {QtQuick2::Date}{Date}
+*/
+
+/*!
+ \qmlmethod string QtQuick2::Locale::monthName(month, type)
+
+ Returns the localized name of \a month (0-11), in the optional
+ \l FortmatType specified by \a type.
+
+ \note the QLocale C++ API expects a range of (1-12), however Locale.monthName()
+ expects 0-11 as per the JS Date object.
+
+ \sa dayName(), standaloneMonthName()
+*/
+
+/*!
+ \qmlmethod string QtQuick2::Locale::standaloneMonthName(month, type)
+
+ Returns the localized name of \a month (0-11) that is used as a
+ standalone text, in the optional \l FormatType specified by \a type.
+
+ If the locale information doesn't specify the standalone month
+ name then return value is the same as in monthName().
+
+ \note the QLocale C++ API expects a range of (1-12), however Locale.standaloneMonthName()
+ expects 0-11 as per the JS Date object.
+
+ \sa monthName(), standaloneDayName()
+*/
+
+/*!
+ \qmlmethod string QtQuick2::Locale::dayName(day, type)
+
+ Returns the localized name of the \a day (where 0 represents
+ Sunday, 1 represents Monday and so on), in the optional
+ \l FormatType specified by \a type.
+
+ \sa monthName(), standaloneDayName()
+*/
+
+/*!
+ \qmlmethod string QtQuick2::Locale::standaloneDayName(day, type)
+
+ Returns the localized name of the \a day (where 0 represents
+ Sunday, 1 represents Monday and so on) that is used as a
+ standalone text, in the \l FormatType specified by \a type.
+
+ If the locale information does not specify the standalone day
+ name then return value is the same as in dayName().
+
+ \sa dayName(), standaloneMonthName()
+*/
+
+/*!
+ \qmlproperty enumeration QtQuick2::Locale::firstDayOfWeek
+
+ Holds the first day of the week according to the current locale.
+
+ \list
+ \o Locale.Sunday = 0
+ \o Locale.Monday = 1
+ \o Locale.Tuesday = 2
+ \o Locale.Wednesday = 3
+ \o Locale.Thursday = 4
+ \o Locale.Friday = 5
+ \o Locale.Saturday = 6
+ \endlist
+
+ \note that these values match the JS Date API which is different
+ from the Qt C++ API where Qt::Sunday = 7.
+*/
+
+/*!
+ \qmlproperty Array<int> QtQuick2::Locale::weekdays
+
+ Holds an array of days that are considered weekdays according to the current locale,
+ where Sunday is 0 and Saturday is 6.
+
+ \sa firstDayOfWeek
+*/
+
+
+/*!
+ \qmlproperty enumeration QtQuick2::Locale::textDirection
+
+ Holds the text direction of the language:
+ \list
+ \o Qt.LeftToRight
+ \o Qt.RightToLeft
+ \endlist
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Locale::amText
+
+ The localized name of the "AM" suffix for times specified using the conventions of the 12-hour clock.
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Locale::pmText
+
+ The localized name of the "PM" suffix for times specified using the conventions of the 12-hour clock.
+*/
+
+/*!
+ \qmlmethod string QtQuick2::Locale::currencySymbol(format)
+
+ Returns the currency symbol for the specified \a format:
+ \list
+ \o Locale.CurrencyIsoCode a ISO-4217 code of the currency.
+ \o Locale.CurrencySymbol a currency symbol.
+ \o Locale.CurrencyDisplayName a user readable name of the currency.
+ \endlist
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Locale::nativeLanguageName
+
+ Holds a native name of the language for the locale. For example
+ "Schwiizertüütsch" for Swiss-German locale.
+
+ \sa nativeCountryName
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Locale::nativeCountryName
+
+ Holds a native name of the country for the locale. For example
+ "España" for Spanish/Spain locale.
+
+ \sa nativeLanguageName
+*/
+
+/*!
+ \qmlproperty enumeration QtQuick2::Locale::measurementSystem
+
+ This property defines which units are used for measurement.
+
+ \list
+ \o Locale.MetricSystem This value indicates metric units, such as meters,
+ centimeters and millimeters.
+ \o Locale.ImperialSystem This value indicates imperial units, such as inches and
+ miles. There are several distinct imperial systems in the world; this
+ value stands for the official United States imperial units.
+ \endlist
+*/
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativelocale_p.h b/src/declarative/qml/qdeclarativelocale_p.h
new file mode 100644
index 0000000000..948729da36
--- /dev/null
+++ b/src/declarative/qml/qdeclarativelocale_p.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVELOCALE_H
+#define QDECLARATIVELOCALE_H
+
+#include <qdeclarative.h>
+
+#include <QtCore/qlocale.h>
+#include <QtCore/qobject.h>
+#include <private/qv8engine_p.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeDateExtension
+{
+public:
+ static void registerExtension(QV8Engine *engine);
+
+private:
+ static v8::Handle<v8::Value> toLocaleString(const v8::Arguments& args);
+ static v8::Handle<v8::Value> toLocaleTimeString(const v8::Arguments& args);
+ static v8::Handle<v8::Value> toLocaleDateString(const v8::Arguments& args);
+ static v8::Handle<v8::Value> fromLocaleString(const v8::Arguments& args);
+ static v8::Handle<v8::Value> fromLocaleTimeString(const v8::Arguments& args);
+ static v8::Handle<v8::Value> fromLocaleDateString(const v8::Arguments& args);
+};
+
+
+class QDeclarativeNumberExtension
+{
+public:
+ static void registerExtension(QV8Engine *engine);
+
+private:
+ static v8::Handle<v8::Value> toLocaleString(const v8::Arguments& args);
+ static v8::Handle<v8::Value> fromLocaleString(const v8::Arguments& args);
+ static v8::Handle<v8::Value> toLocaleCurrencyString(const v8::Arguments& args);
+};
+
+
+class Q_AUTOTEST_EXPORT QDeclarativeLocale
+{
+ Q_GADGET
+ Q_ENUMS(MeasurementSystem)
+ Q_ENUMS(FormatType)
+ Q_ENUMS(CurrencySymbolFormat)
+ Q_ENUMS(DayOfWeek)
+
+public:
+ ~QDeclarativeLocale();
+
+ enum MeasurementSystem {
+ MetricSystem = QLocale::MetricSystem,
+ ImperialSystem = QLocale::ImperialSystem
+ };
+ enum FormatType {
+ LongFormat = QLocale::LongFormat,
+ ShortFormat = QLocale::ShortFormat,
+ NarrowFormat = QLocale::NarrowFormat
+ };
+ enum CurrencySymbolFormat {
+ CurrencyIsoCode = QLocale::CurrencyIsoCode,
+ CurrencySymbol = QLocale::CurrencySymbol,
+ CurrencyDisplayName = QLocale::CurrencyDisplayName
+ };
+ // Qt defines Sunday as 7, but JS Date assigns Sunday 0
+ enum DayOfWeek {
+ Sunday = 0,
+ Monday = Qt::Monday,
+ Tuesday = Qt::Tuesday,
+ Wednesday = Qt::Wednesday,
+ Thursday = Qt::Thursday,
+ Friday = Qt::Friday,
+ Saturday = Qt::Saturday
+ };
+
+ static v8::Handle<v8::Value> locale(QV8Engine *v8engine, const QString &lang);
+
+private:
+ QDeclarativeLocale();
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index b14e547f40..a920d62a2a 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -43,6 +43,7 @@ SOURCES += \
$$PWD/qdeclarativeextensionplugin.cpp \
$$PWD/qdeclarativeimport.cpp \
$$PWD/qdeclarativelist.cpp \
+ $$PWD/qdeclarativelocale.cpp \
HEADERS += \
$$PWD/qdeclarativeglobal_p.h \
@@ -104,7 +105,8 @@ HEADERS += \
$$PWD/qdeclarativeimport_p.h \
$$PWD/qdeclarativeextensionplugin.h \
$$PWD/qdeclarativenullablevalue_p_p.h \
- $$PWD/qdeclarativescriptstring_p.h
+ $$PWD/qdeclarativescriptstring_p.h \
+ $$PWD/qdeclarativelocale_p.h \
QT += sql
include(parser/parser.pri)
diff --git a/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp b/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp
index 84b42f6d7f..a822eb84ec 100644
--- a/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp
+++ b/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp
@@ -45,6 +45,7 @@
#include <private/qdeclarativeengine_p.h>
#include <private/qdeclarativecomponent_p.h>
#include <private/qdeclarativestringconverters_p.h>
+#include <private/qdeclarativelocale_p.h>
#include <private/qv8engine_p.h>
#include <QtCore/qstring.h>
@@ -521,6 +522,8 @@ the possible format values as described for
If \a format is not specified, \a date is formatted using
\l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
+
+\sa Locale
*/
v8::Handle<v8::Value> formatDate(const v8::Arguments &args)
{
@@ -560,6 +563,8 @@ described for \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
If \a format is not specified, \a time is formatted using
\l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
+
+\sa Locale
*/
v8::Handle<v8::Value> formatTime(const v8::Arguments &args)
{
@@ -680,6 +685,8 @@ with the \a format values below to produce the following results:
\row \i "hh:mm:ss.zzz" \i 14:13:09.042
\row \i "h:m:s ap" \i 2:13:9 pm
\endtable
+
+ \sa Locale
*/
v8::Handle<v8::Value> formatDateTime(const v8::Arguments &args)
{
@@ -1087,6 +1094,42 @@ v8::Handle<v8::Value> qsTrIdNoOp(const v8::Arguments &args)
return args[0];
}
+
+/*!
+ \qmlmethod Qt::locale(name)
+
+ Returns a JS object representing the locale with the specified
+ name, which has the format "language[_territory][.codeset][@modifier]"
+ or "C", where:
+
+ \list
+ \o language is a lowercase, two-letter, ISO 639 language code,
+ \o territory is an uppercase, two-letter, ISO 3166 country code,
+ \o and codeset and modifier are ignored.
+ \endlist
+
+ If the string violates the locale format, or language is not a
+ valid ISO 369 code, the "C" locale is used instead. If country
+ is not present, or is not a valid ISO 3166 code, the most
+ appropriate country is chosen for the specified language.
+
+ \sa QtQuick2::Locale
+*/
+v8::Handle<v8::Value> locale(const v8::Arguments &args)
+{
+ QString code;
+ if (args.Length() > 1)
+ V8THROW_ERROR("locale() requires 0 or 1 argument");
+ if (args.Length() == 1 && !args[0]->IsString())
+ V8THROW_TYPE("locale(): argument (locale code) must be a string");
+
+ QV8Engine *v8engine = V8ENGINE();
+ if (args.Length() == 1)
+ code = v8engine->toString(args[0]);
+
+ return QDeclarativeLocale::locale(v8engine, code);
+}
+
} // namespace QDeclarativeBuiltinFunctions
QT_END_NAMESPACE
diff --git a/src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h b/src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h
index 8810f77df4..8a4ac06f6c 100644
--- a/src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h
+++ b/src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h
@@ -96,6 +96,7 @@ v8::Handle<v8::Value> qsTrNoOp(const v8::Arguments &args);
v8::Handle<v8::Value> qsTrId(const v8::Arguments &args);
v8::Handle<v8::Value> qsTrIdNoOp(const v8::Arguments &args);
v8::Handle<v8::Value> stringArg(const v8::Arguments &args);
+v8::Handle<v8::Value> locale(const v8::Arguments &args);
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/v8/qjsengine.cpp b/src/declarative/qml/v8/qjsengine.cpp
index 084640bb14..e0fc36727d 100644
--- a/src/declarative/qml/v8/qjsengine.cpp
+++ b/src/declarative/qml/v8/qjsengine.cpp
@@ -22,6 +22,7 @@
****************************************************************************/
#include "qjsengine.h"
+#include "qjsengine_p.h"
#include "qjsvalue.h"
#include "qjsvalue_p.h"
#include "qscriptisolate_p.h"
@@ -178,7 +179,7 @@ QJSEngine::QJSEngine(QObject *parent)
{
}
-QJSEngine::QJSEngine(QObjectPrivate &dd, QObject *parent)
+QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent)
: QObject(dd, parent)
, d(new QV8Engine(this))
{
diff --git a/src/declarative/qml/v8/qjsengine.h b/src/declarative/qml/v8/qjsengine.h
index 759363ab84..c941d0c9e3 100644
--- a/src/declarative/qml/v8/qjsengine.h
+++ b/src/declarative/qml/v8/qjsengine.h
@@ -45,6 +45,7 @@ class QRegExp;
template <typename T>
inline T qjsvalue_cast(const QJSValue &);
+class QJSEnginePrivate;
class Q_DECLARATIVE_EXPORT QJSEngine
: public QObject
{
@@ -111,11 +112,12 @@ private:
friend inline bool qjsvalue_cast_helper(const QJSValue &, int, void *);
protected:
- QJSEngine(QObjectPrivate &dd, QObject *parent = 0);
+ QJSEngine(QJSEnginePrivate &dd, QObject *parent = 0);
private:
QV8Engine *d;
Q_DISABLE_COPY(QJSEngine)
+ Q_DECLARE_PRIVATE(QJSEngine)
friend class QV8Engine;
};
diff --git a/src/declarative/qml/v8/qjsengine_p.h b/src/declarative/qml/v8/qjsengine_p.h
new file mode 100644
index 0000000000..46f8754af4
--- /dev/null
+++ b/src/declarative/qml/v8/qjsengine_p.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtScript module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QJSENGINE_P_H
+#define QJSENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qobject_p.h>
+#include "qjsengine.h"
+
+
+QT_BEGIN_NAMESPACE
+
+
+class QJSEnginePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QJSEngine)
+
+public:
+ static QJSEnginePrivate* get(QJSEngine*e) { return e->d_func(); }
+
+ QJSEnginePrivate() {}
+};
+
+QT_END_NAMESPACE
+
+#endif // QJSENGINE_P_H
diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp
index 791c972c0b..7c4ebff7c1 100644
--- a/src/declarative/qml/v8/qv8engine.cpp
+++ b/src/declarative/qml/v8/qv8engine.cpp
@@ -47,6 +47,7 @@
#include "qv8gccallback_p.h"
#include "qv8sequencewrapper_p.h"
#include "qv8include_p.h"
+#include "qjsengine_p.h"
#include "../../../3rdparty/javascriptcore/DateMath.h"
#include <private/qdeclarativebuiltinfunctions_p.h>
@@ -55,6 +56,7 @@
#include <private/qdeclarativeapplication_p.h>
#include <private/qdeclarativexmlhttprequest_p.h>
#include <private/qdeclarativesqldatabase_p.h>
+#include <private/qdeclarativelocale_p.h>
#include "qscript_impl_p.h"
#include "qv8domerrors_p.h"
@@ -113,6 +115,7 @@ static bool ObjectComparisonCallback(v8::Local<v8::Object> lhs, v8::Local<v8::Ob
return false;
}
+
QV8Engine::QV8Engine(QJSEngine* qq, QJSEngine::ContextOwnership ownership)
: q(qq)
, m_engine(0)
@@ -226,6 +229,7 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint)
case QV8ObjectResource::ListModelType:
case QV8ObjectResource::Context2DType:
case QV8ObjectResource::ParticleDataType:
+ case QV8ObjectResource::LocaleDataType:
return QVariant();
case QV8ObjectResource::TypeType:
return m_typeWrapper.toVariant(r);
@@ -565,6 +569,7 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
qt->Set(v8::String::New("btoa"), V8FUNCTION(btoa, this));
qt->Set(v8::String::New("atob"), V8FUNCTION(atob, this));
qt->Set(v8::String::New("resolvedUrl"), V8FUNCTION(resolvedUrl, this));
+ qt->Set(v8::String::New("locale"), V8FUNCTION(locale, this));
if (m_engine) {
qt->Set(v8::String::New("application"), newQObject(new QDeclarativeApplication(m_engine)));
@@ -604,6 +609,9 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
#undef STRING_ARG
}
+ QDeclarativeDateExtension::registerExtension(this);
+ QDeclarativeNumberExtension::registerExtension(this);
+
qt_add_domexceptions(this);
m_xmlHttpRequestData = qt_add_qmlxmlhttprequest(this);
m_sqlDatabaseData = qt_add_qmlsqldatabase(this);
diff --git a/src/declarative/qml/v8/qv8engine_p.h b/src/declarative/qml/v8/qv8engine_p.h
index 7b85cfcc31..acf7ec816a 100644
--- a/src/declarative/qml/v8/qv8engine_p.h
+++ b/src/declarative/qml/v8/qv8engine_p.h
@@ -139,7 +139,7 @@ public:
ValueTypeType, XMLHttpRequestType, DOMNodeType, SQLDatabaseType,
ListModelType, Context2DType, Context2DStyleType, Context2DPixelArrayType,
ParticleDataType, SignalHandlerType, IncubatorType, VisualDataItemType,
- SequenceType };
+ SequenceType, LocaleDataType };
virtual ResourceType resourceType() const = 0;
QV8Engine *engine;
@@ -412,6 +412,9 @@ public:
QObject *qtObjectFromJS(v8::Handle<v8::Value> value);
QSet<int> visitedConversionObjects;
+
+ static QDateTime qtDateTimeFromJsDate(double jsDate);
+
protected:
QJSEngine* q;
QDeclarativeEngine *m_engine;
@@ -449,7 +452,6 @@ protected:
void initializeGlobal(v8::Handle<v8::Object>);
double qtDateTimeToJsDate(const QDateTime &dt);
- QDateTime qtDateTimeFromJsDate(double jsDate);
private:
typedef QScriptIntrusiveList<QJSValuePrivate, &QJSValuePrivate::m_node> ValueList;
diff --git a/src/declarative/qml/v8/script.pri b/src/declarative/qml/v8/script.pri
index 587ab6f42d..3439413f5e 100644
--- a/src/declarative/qml/v8/script.pri
+++ b/src/declarative/qml/v8/script.pri
@@ -5,6 +5,7 @@ SOURCES += \
HEADERS += \
$$PWD/qjsengine.h \
+ $$PWD/qjsengine_p.h \
$$PWD/qjsvalue.h \
$$PWD/qjsvalue_p.h \
$$PWD/qjsvalueiterator.h \
diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro
index 7cb9d33576..0d19af9a6c 100644
--- a/tests/auto/declarative/declarative.pro
+++ b/tests/auto/declarative/declarative.pro
@@ -22,6 +22,7 @@ PUBLICTESTS += \
qdeclarativeqt \
qdeclarativetranslation \
qdeclarativexmlhttprequest \
+ qdeclarativelocale \
qjsvalue \
qjsvalueiterator \
qjsengine \
diff --git a/tests/auto/declarative/qdeclarativelocale/data/date.qml b/tests/auto/declarative/qdeclarativelocale/data/date.qml
new file mode 100644
index 0000000000..3f58497d22
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelocale/data/date.qml
@@ -0,0 +1,45 @@
+import QtQuick 2.0
+
+QtObject {
+ property var locale: Qt.locale()
+
+ function setLocale(l) {
+ locale = Qt.locale(l)
+ }
+
+ function toLocaleString(fmt) {
+ var d = new Date(2011, 9, 7, 18, 53, 48, 345);
+ if (fmt < 0)
+ return d.toLocaleString(locale);
+ else
+ return d.toLocaleString(locale, fmt);
+ }
+
+ function toLocaleDateString(fmt) {
+ var d = new Date(2011, 9, 7, 18, 53, 48, 345);
+ if (fmt < 0)
+ return d.toLocaleDateString(locale);
+ else
+ return d.toLocaleDateString(locale, fmt);
+ }
+
+ function toLocaleTimeString(fmt) {
+ var d = new Date(2011, 9, 7, 18, 53, 48, 345);
+ if (fmt < 0)
+ return d.toLocaleTimeString(locale);
+ else
+ return d.toLocaleTimeString(locale, fmt);
+ }
+
+ function fromLocaleString(d,fmt) {
+ return Date.fromLocaleString(locale, d, fmt)
+ }
+
+ function fromLocaleDateString(d,fmt) {
+ return Date.fromLocaleDateString(locale, d, fmt)
+ }
+
+ function fromLocaleTimeString(d,fmt) {
+ return Date.fromLocaleTimeString(locale, d, fmt)
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativelocale/data/functions.qml b/tests/auto/declarative/qdeclarativelocale/data/functions.qml
new file mode 100644
index 0000000000..5fef6a26fb
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelocale/data/functions.qml
@@ -0,0 +1,65 @@
+import QtQuick 2.0
+
+QtObject {
+ property var locale: Qt.locale()
+
+ function setLocale(l) {
+ locale = Qt.locale(l)
+ }
+
+ function currencySymbol(type) {
+ if (type < 0)
+ return locale.currencySymbol()
+ else
+ return locale.currencySymbol(type)
+ }
+
+ function monthName(month,type) {
+ if (type < 0)
+ return locale.monthName(month)
+ else
+ return locale.monthName(month, type)
+ }
+
+ function standaloneMonthName(month,type) {
+ if (type < 0)
+ return locale.standaloneMonthName(month)
+ else
+ return locale.standaloneMonthName(month, type)
+ }
+
+ function dayName(month,type) {
+ if (type < 0)
+ return locale.dayName(month)
+ else
+ return locale.dayName(month, type)
+ }
+
+ function standaloneDayName(month,type) {
+ if (type < 0)
+ return locale.standaloneDayName(month)
+ else
+ return locale.standaloneDayName(month, type)
+ }
+
+ function dateTimeFormat(fmt) {
+ if (fmt < 0)
+ return locale.dateTimeFormat()
+ else
+ return locale.dateTimeFormat(fmt)
+ }
+
+ function dateFormat(fmt) {
+ if (fmt < 0)
+ return locale.dateFormat()
+ else
+ return locale.dateFormat(fmt)
+ }
+
+ function timeFormat(fmt) {
+ if (fmt < 0)
+ return locale.timeFormat()
+ else
+ return locale.timeFormat(fmt)
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativelocale/data/number.qml b/tests/auto/declarative/qdeclarativelocale/data/number.qml
new file mode 100644
index 0000000000..51a6c15dce
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelocale/data/number.qml
@@ -0,0 +1,30 @@
+import QtQuick 2.0
+
+QtObject {
+ property var locale: Qt.locale()
+
+ function setLocale(l) {
+ locale = Qt.locale(l)
+ }
+
+ function toLocaleString(n,fmt,prec) {
+ if (prec < 0)
+ return n.toLocaleString(locale, fmt);
+ else
+ return n.toLocaleString(locale, fmt, prec);
+ }
+
+ function toLocaleCurrencyString(n,symbol) {
+ if (symbol.length == 0)
+ return n.toLocaleCurrencyString(locale);
+ else
+ return n.toLocaleCurrencyString(locale, symbol);
+ }
+
+ function fromLocaleString(n) {
+ return Number.fromLocaleString(locale, n)
+ }
+
+ property var const1: 1234.56.toLocaleString(locale);
+ property var const2: 1234..toLocaleString(locale);
+}
diff --git a/tests/auto/declarative/qdeclarativelocale/data/properties.qml b/tests/auto/declarative/qdeclarativelocale/data/properties.qml
new file mode 100644
index 0000000000..1d2968b419
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelocale/data/properties.qml
@@ -0,0 +1,26 @@
+import QtQuick 2.0
+
+QtObject {
+ property var locale: Qt.locale()
+
+ function setLocale(l) {
+ locale = Qt.locale(l);
+ }
+
+ property var name: locale.name
+ property var amText: locale.amText
+ property var pmText: locale.pmText
+ property var nativeLanguageName: locale.nativeLanguageName
+ property var nativeCountryName: locale.nativeCountryName
+ property var decimalPoint: locale.decimalPoint
+ property var groupSeparator: locale.groupSeparator
+ property var percent: locale.percent
+ property var zeroDigit: locale.zeroDigit
+ property var negativeSign: locale.negativeSign
+ property var positiveSign: locale.positiveSign
+ property var exponential: locale.exponential
+ property var firstDayOfWeek: locale.firstDayOfWeek
+ property var measurementSystem: locale.measurementSystem
+ property var textDirection: locale.textDirection
+ property var weekDays: locale.weekDays
+}
diff --git a/tests/auto/declarative/qdeclarativelocale/qdeclarativelocale.pro b/tests/auto/declarative/qdeclarativelocale/qdeclarativelocale.pro
new file mode 100644
index 0000000000..05ce0fec6a
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelocale/qdeclarativelocale.pro
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TARGET = tst_qdeclarativelocale
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qdeclarativelocale.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += declarative testlib
diff --git a/tests/auto/declarative/qdeclarativelocale/tst_qdeclarativelocale.cpp b/tests/auto/declarative/qdeclarativelocale/tst_qdeclarativelocale.cpp
new file mode 100644
index 0000000000..54139a2671
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelocale/tst_qdeclarativelocale.cpp
@@ -0,0 +1,1090 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <QDebug>
+
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qquickitem.h>
+#include <QtCore/QDateTime>
+#include <qcolor.h>
+#include "../shared/util.h"
+
+class tst_qdeclarativelocale : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qdeclarativelocale() { }
+
+private slots:
+ void properties_data();
+ void properties();
+ void currencySymbol_data();
+ void currencySymbol();
+ void monthName_data();
+ void monthName();
+ void standaloneMonthName_data();
+ void standaloneMonthName();
+ void dayName_data();
+ void dayName();
+ void standaloneDayName_data();
+ void standaloneDayName();
+ void weekDays_data();
+ void weekDays();
+ void dateFormat_data();
+ void dateFormat();
+ void dateTimeFormat_data();
+ void dateTimeFormat();
+ void timeFormat_data();
+ void timeFormat();
+
+ void dateToLocaleString_data();
+ void dateToLocaleString();
+ void dateToLocaleStringFormatted_data();
+ void dateToLocaleStringFormatted();
+ void dateToLocaleDateString_data();
+ void dateToLocaleDateString();
+ void dateToLocaleDateStringFormatted_data();
+ void dateToLocaleDateStringFormatted();
+ void dateToLocaleTimeString_data();
+ void dateToLocaleTimeString();
+ void dateToLocaleTimeStringFormatted_data();
+ void dateToLocaleTimeStringFormatted();
+ void dateFromLocaleString_data();
+ void dateFromLocaleString();
+ void dateFromLocaleDateString_data();
+ void dateFromLocaleDateString();
+ void dateFromLocaleTimeString_data();
+ void dateFromLocaleTimeString();
+
+ void numberToLocaleString_data();
+ void numberToLocaleString();
+ void numberToLocaleCurrencyString_data();
+ void numberToLocaleCurrencyString();
+ void numberFromLocaleString_data();
+ void numberFromLocaleString();
+ void numberConstToLocaleString();
+
+private:
+ void addPropertyData(const QString &l);
+ QVariant getProperty(QObject *obj, const QString &locale, const QString &property);
+ void addCurrencySymbolData(const QString &locale);
+ void addStandardFormatData();
+ void addFormatNameData(const QString &locale);
+ void addDateTimeFormatData(const QString &l);
+ void addDateFormatData(const QString &l);
+ void addTimeFormatData(const QString &l);
+ QDeclarativeEngine engine;
+};
+
+#define LOCALE_PROP(type,prop) { #prop, QVariant(type(qlocale.prop())) }
+
+void tst_qdeclarativelocale::addPropertyData(const QString &l)
+{
+ QLocale qlocale(l);
+
+ struct {
+ const char *name;
+ QVariant value;
+ }
+ values[] = {
+ LOCALE_PROP(QString,name),
+ LOCALE_PROP(QString,amText),
+ LOCALE_PROP(QString,pmText),
+ LOCALE_PROP(QString,nativeLanguageName),
+ LOCALE_PROP(QString,nativeCountryName),
+ LOCALE_PROP(QString,decimalPoint),
+ LOCALE_PROP(QString,groupSeparator),
+ LOCALE_PROP(QString,percent),
+ LOCALE_PROP(QString,zeroDigit),
+ LOCALE_PROP(QString,negativeSign),
+ LOCALE_PROP(QString,positiveSign),
+ LOCALE_PROP(QString,exponential),
+ LOCALE_PROP(int,firstDayOfWeek),
+ LOCALE_PROP(int,measurementSystem),
+ LOCALE_PROP(int,textDirection),
+ { 0, QVariant() }
+ };
+
+ int i = 0;
+ while (values[i].name) {
+ QByteArray n = l.toLatin1() + ':' + values[i].name;
+ QTest::newRow(n.constData()) << l << QByteArray(values[i].name) << values[i].value;
+ ++i;
+ }
+}
+
+void tst_qdeclarativelocale::properties_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QByteArray>("property");
+ QTest::addColumn<QVariant>("value");
+
+ addPropertyData("en_US");
+ addPropertyData("de_DE");
+ addPropertyData("ar_SA");
+ addPropertyData("hi_IN");
+ addPropertyData("zh_CN");
+ addPropertyData("th_TH");
+}
+
+void tst_qdeclarativelocale::properties()
+{
+ QFETCH(QString, locale);
+ QFETCH(QByteArray, property);
+ QFETCH(QVariant, value);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QCOMPARE(obj->property(property), value);
+
+ delete obj;
+}
+
+void tst_qdeclarativelocale::addCurrencySymbolData(const QString &l)
+{
+ QByteArray locale = l.toLatin1();
+ QTest::newRow(locale.constData()) << l << -1;
+ QByteArray t(locale);
+ t += " CurrencyIsoCode";
+ QTest::newRow(t.constData()) << l << (int)QLocale::CurrencyIsoCode;
+ t = locale + " CurrencySymbol";
+ QTest::newRow(t.constData()) << l << (int)QLocale::CurrencySymbol;
+ t = locale + " CurrencyDisplayName";
+ QTest::newRow(t.constData()) << l << (int)QLocale::CurrencyDisplayName;
+}
+
+void tst_qdeclarativelocale::currencySymbol_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<int>("param");
+
+ addCurrencySymbolData("en_US");
+ addCurrencySymbolData("de_DE");
+ addCurrencySymbolData("ar_SA");
+ addCurrencySymbolData("hi_IN");
+ addCurrencySymbolData("zh_CN");
+ addCurrencySymbolData("th_TH");
+}
+
+void tst_qdeclarativelocale::currencySymbol()
+{
+ QFETCH(QString, locale);
+ QFETCH(int, param);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("functions.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QLocale l(locale);
+ QVariant val;
+ QLocale::CurrencySymbolFormat format = QLocale::CurrencySymbol;
+
+ if (param >= 0)
+ format = QLocale::CurrencySymbolFormat(param);
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QMetaObject::invokeMethod(obj, "currencySymbol", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(int(format))));
+
+ QCOMPARE(val.toString(), l.currencySymbol(format));
+
+ delete obj;
+}
+
+void tst_qdeclarativelocale::addFormatNameData(const QString &l)
+{
+ QByteArray locale = l.toLatin1();
+ QTest::newRow(locale.constData()) << l << -1;
+ QByteArray t(locale);
+ t += " LongFormat";
+ QTest::newRow(t.constData()) << l << (int)QLocale::LongFormat;
+ t = locale + " ShortFormat";
+ QTest::newRow(t.constData()) << l << (int)QLocale::ShortFormat;
+ t = locale + " NarrowFormat";
+ QTest::newRow(t.constData()) << l << (int)QLocale::NarrowFormat;
+}
+
+void tst_qdeclarativelocale::addStandardFormatData()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<int>("param");
+
+ addFormatNameData("en_US");
+ addFormatNameData("de_DE");
+ addFormatNameData("ar_SA");
+ addFormatNameData("hi_IN");
+ addFormatNameData("zh_CN");
+ addFormatNameData("th_TH");
+}
+
+void tst_qdeclarativelocale::monthName_data()
+{
+ addStandardFormatData();
+}
+
+void tst_qdeclarativelocale::monthName()
+{
+ QFETCH(QString, locale);
+ QFETCH(int, param);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("functions.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QLocale l(locale);
+ QVariant val;
+ QLocale::FormatType format = QLocale::LongFormat;
+ if (param >= 0)
+ format = QLocale::FormatType(param);
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ for (int i = 0; i <= 11; ++i) {
+ QMetaObject::invokeMethod(obj, "monthName", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(i)),
+ Q_ARG(QVariant, QVariant(int(format))));
+
+ // QLocale January == 1, JS Date January == 0
+ QCOMPARE(val.toString(), l.monthName(i+1, format));
+ }
+
+ delete obj;
+}
+
+void tst_qdeclarativelocale::standaloneMonthName_data()
+{
+ addStandardFormatData();
+}
+
+void tst_qdeclarativelocale::standaloneMonthName()
+{
+ QFETCH(QString, locale);
+ QFETCH(int, param);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("functions.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QLocale l(locale);
+ QVariant val;
+ QLocale::FormatType format = QLocale::LongFormat;
+ if (param >= 0)
+ format = QLocale::FormatType(param);
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ for (int i = 0; i <= 11; ++i) {
+ QMetaObject::invokeMethod(obj, "standaloneMonthName", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(i)),
+ Q_ARG(QVariant, QVariant(int(format))));
+
+ // QLocale January == 1, JS Date January == 0
+ QCOMPARE(val.toString(), l.standaloneMonthName(i+1, format));
+ }
+
+ delete obj;
+}
+
+void tst_qdeclarativelocale::dayName_data()
+{
+ addStandardFormatData();
+}
+
+void tst_qdeclarativelocale::dayName()
+{
+ QFETCH(QString, locale);
+ QFETCH(int, param);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("functions.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QLocale l(locale);
+ QVariant val;
+ QLocale::FormatType format = QLocale::LongFormat;
+ if (param >= 0)
+ format = QLocale::FormatType(param);
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ for (int i = 1; i <= 7; ++i) {
+ QMetaObject::invokeMethod(obj, "dayName", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(i)),
+ Q_ARG(QVariant, QVariant(int(format))));
+
+ QCOMPARE(val.toString(), l.dayName(i, format));
+ }
+
+ delete obj;
+}
+
+void tst_qdeclarativelocale::standaloneDayName_data()
+{
+ addStandardFormatData();
+}
+
+void tst_qdeclarativelocale::standaloneDayName()
+{
+ QFETCH(QString, locale);
+ QFETCH(int, param);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("functions.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QLocale l(locale);
+ QVariant val;
+ QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param);
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ for (int i = 1; i <= 7; ++i) {
+ QMetaObject::invokeMethod(obj, "standaloneDayName", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(i)),
+ Q_ARG(QVariant, QVariant(int(format))));
+
+ QCOMPARE(val.toString(), l.standaloneDayName(i, format));
+ }
+
+ delete obj;
+}
+
+void tst_qdeclarativelocale::weekDays_data()
+{
+ QTest::addColumn<QString>("locale");
+
+ QTest::newRow("en_US") << "en_US";
+ QTest::newRow("de_DE") << "de_DE";
+ QTest::newRow("ar_SA") << "ar_SA";
+ QTest::newRow("hi_IN") << "hi_IN";
+ QTest::newRow("zh_CN") << "zh_CN";
+ QTest::newRow("th_TH") << "th_TH";
+}
+
+void tst_qdeclarativelocale::weekDays()
+{
+ QFETCH(QString, locale);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QVariant val = obj->property("weekDays");
+ QVERIFY(val.type() == QVariant::List);
+
+ QList<QVariant> qmlDays = val.toList();
+ QList<Qt::DayOfWeek> days = QLocale(locale).weekdays();
+
+ QVERIFY(days.count() == qmlDays.count());
+
+ for (int i = 0; i < days.count(); ++i) {
+ int day = int(days.at(i));
+ if (day == 7) // JS Date days in range 0(Sunday) to 6(Saturday)
+ day = 0;
+ QCOMPARE(day, qmlDays.at(i).toInt());
+ }
+
+ delete obj;
+}
+
+
+void tst_qdeclarativelocale::dateTimeFormat_data()
+{
+ addStandardFormatData();
+}
+
+void tst_qdeclarativelocale::dateTimeFormat()
+{
+ QFETCH(QString, locale);
+ QFETCH(int, param);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("functions.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QLocale l(locale);
+ QVariant val;
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param);
+ QMetaObject::invokeMethod(obj, "dateTimeFormat", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(param)));
+
+ QCOMPARE(val.toString(), l.dateTimeFormat(format));
+}
+
+void tst_qdeclarativelocale::dateFormat_data()
+{
+ addStandardFormatData();
+}
+
+void tst_qdeclarativelocale::dateFormat()
+{
+ QFETCH(QString, locale);
+ QFETCH(int, param);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("functions.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QLocale l(locale);
+ QVariant val;
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param);
+ QMetaObject::invokeMethod(obj, "dateFormat", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(param)));
+
+ QCOMPARE(val.toString(), l.dateFormat(format));
+}
+
+void tst_qdeclarativelocale::timeFormat_data()
+{
+ addStandardFormatData();
+}
+
+void tst_qdeclarativelocale::timeFormat()
+{
+ QFETCH(QString, locale);
+ QFETCH(int, param);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("functions.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QLocale l(locale);
+ QVariant val;
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param);
+ QMetaObject::invokeMethod(obj, "timeFormat", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(param)));
+
+ QCOMPARE(val.toString(), l.timeFormat(format));
+}
+
+void tst_qdeclarativelocale::dateToLocaleString_data()
+{
+ addStandardFormatData();
+}
+
+void tst_qdeclarativelocale::dateToLocaleString()
+{
+ QFETCH(QString, locale);
+ QFETCH(int, param);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("date.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QDateTime dt;
+ dt.setDate(QDate(2011, 10, 7)); // weirdly, JS Date month range is 0-11
+ dt.setTime(QTime(18, 53, 48, 345));
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param);
+
+ QVariant val;
+ QMetaObject::invokeMethod(obj, "toLocaleString", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(param)));
+
+ QLocale l(locale);
+ QCOMPARE(val.toString(), l.toString(dt, format));
+}
+
+void tst_qdeclarativelocale::addDateTimeFormatData(const QString &l)
+{
+ const char *formats[] = {
+ "hh:mm dd.MM.yyyy",
+ "h:m:sap ddd MMMM d yy",
+ "'The date and time is: 'H:mm:ss:zzz dd/MM/yy",
+ "MMM d yyyy HH:mm t",
+ 0
+ };
+ QByteArray locale = l.toLatin1();
+ int i = 0;
+ while (formats[i]) {
+ QByteArray t(locale);
+ t += " ";
+ t += formats[i];
+ QTest::newRow(t.constData()) << l << QString(formats[i]);
+ ++i;
+ }
+}
+
+void tst_qdeclarativelocale::dateToLocaleStringFormatted_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("format");
+
+ addDateTimeFormatData("en_US");
+ addDateTimeFormatData("de_DE");
+ addDateTimeFormatData("ar_SA");
+ addDateTimeFormatData("hi_IN");
+ addDateTimeFormatData("zh_CN");
+ addDateTimeFormatData("th_TH");
+}
+
+void tst_qdeclarativelocale::dateToLocaleStringFormatted()
+{
+ QFETCH(QString, locale);
+ QFETCH(QString, format);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("date.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QDateTime dt;
+ dt.setDate(QDate(2011, 10, 7)); // weirdly, JS Date month range is 0-11
+ dt.setTime(QTime(18, 53, 48, 345));
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QVariant val;
+ QMetaObject::invokeMethod(obj, "toLocaleString", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(format)));
+
+ QLocale l(locale);
+ QCOMPARE(val.toString(), l.toString(dt, format));
+}
+
+void tst_qdeclarativelocale::dateToLocaleDateString_data()
+{
+ addStandardFormatData();
+}
+
+void tst_qdeclarativelocale::dateToLocaleDateString()
+{
+ QFETCH(QString, locale);
+ QFETCH(int, param);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("date.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QDateTime dt;
+ dt.setDate(QDate(2011, 10, 7)); // weirdly, JS Date month range is 0-11
+ dt.setTime(QTime(18, 53, 48, 345));
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param);
+
+ QVariant val;
+ QMetaObject::invokeMethod(obj, "toLocaleDateString", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(param)));
+
+ QLocale l(locale);
+ QCOMPARE(val.toString(), l.toString(dt.date(), format));
+}
+
+void tst_qdeclarativelocale::addDateFormatData(const QString &l)
+{
+ const char *formats[] = {
+ "dd.MM.yyyy",
+ "ddd MMMM d yy",
+ "'The date is: 'dd/MM/yy",
+ "MMM d yyyy",
+ 0
+ };
+ QByteArray locale = l.toLatin1();
+ int i = 0;
+ while (formats[i]) {
+ QByteArray t(locale);
+ t += " ";
+ t += formats[i];
+ QTest::newRow(t.constData()) << l << QString(formats[i]);
+ ++i;
+ }
+}
+
+void tst_qdeclarativelocale::dateToLocaleDateStringFormatted_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("format");
+
+ addDateFormatData("en_US");
+ addDateFormatData("de_DE");
+ addDateFormatData("ar_SA");
+ addDateFormatData("hi_IN");
+ addDateFormatData("zh_CN");
+ addDateFormatData("th_TH");
+}
+
+void tst_qdeclarativelocale::dateToLocaleDateStringFormatted()
+{
+ QFETCH(QString, locale);
+ QFETCH(QString, format);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("date.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QDateTime dt;
+ dt.setDate(QDate(2011, 10, 7)); // weirdly, JS Date month range is 0-11
+ dt.setTime(QTime(18, 53, 48, 345));
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QVariant val;
+ QMetaObject::invokeMethod(obj, "toLocaleString", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(format)));
+
+ QLocale l(locale);
+ QCOMPARE(val.toString(), l.toString(dt.date(), format));
+}
+
+void tst_qdeclarativelocale::dateToLocaleTimeString_data()
+{
+ addStandardFormatData();
+}
+
+void tst_qdeclarativelocale::dateToLocaleTimeString()
+{
+ QFETCH(QString, locale);
+ QFETCH(int, param);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("date.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QDateTime dt;
+ dt.setDate(QDate(2011, 10, 7)); // weirdly, JS Date month range is 0-11
+ dt.setTime(QTime(18, 53, 48, 345));
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param);
+
+ QVariant val;
+ QMetaObject::invokeMethod(obj, "toLocaleTimeString", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(param)));
+
+ QLocale l(locale);
+ QCOMPARE(val.toString(), l.toString(dt.time(), format));
+}
+
+void tst_qdeclarativelocale::addTimeFormatData(const QString &l)
+{
+ const char *formats[] = {
+ "hh:mm",
+ "h:m:sap",
+ "'The time is: 'H:mm:ss:zzz",
+ "HH:mm t",
+ 0
+ };
+ QByteArray locale = l.toLatin1();
+ int i = 0;
+ while (formats[i]) {
+ QByteArray t(locale);
+ t += " ";
+ t += formats[i];
+ QTest::newRow(t.constData()) << l << QString(formats[i]);
+ ++i;
+ }
+}
+
+void tst_qdeclarativelocale::dateToLocaleTimeStringFormatted_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("format");
+
+ addTimeFormatData("en_US");
+ addTimeFormatData("de_DE");
+ addTimeFormatData("ar_SA");
+ addTimeFormatData("hi_IN");
+ addTimeFormatData("zh_CN");
+ addTimeFormatData("th_TH");
+}
+
+void tst_qdeclarativelocale::dateToLocaleTimeStringFormatted()
+{
+ QFETCH(QString, locale);
+ QFETCH(QString, format);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("date.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QDateTime dt;
+ dt.setDate(QDate(2011, 10, 7)); // weirdly, JS Date month range is 0-11
+ dt.setTime(QTime(18, 53, 48, 345));
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QVariant val;
+ QMetaObject::invokeMethod(obj, "toLocaleString", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(format)));
+
+ QLocale l(locale);
+ QCOMPARE(val.toString(), l.toString(dt.time(), format));
+}
+
+void tst_qdeclarativelocale::dateFromLocaleString_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("format");
+
+ QTest::newRow("en_US 1") << "en_US" << "dddd, MMMM d, yyyy h:mm:ss AP";
+ QTest::newRow("en_US long") << "en_US" << QLocale("en_US").dateTimeFormat();
+ QTest::newRow("en_US short") << "en_US" << QLocale("en_US").dateTimeFormat(QLocale::ShortFormat);
+ QTest::newRow("de_DE long") << "de_DE" << QLocale("de_DE").dateTimeFormat();
+ QTest::newRow("de_DE short") << "de_DE" << QLocale("de_DE").dateTimeFormat(QLocale::ShortFormat);
+ QTest::newRow("ar_SA long") << "ar_SA" << QLocale("ar_SA").dateTimeFormat();
+ QTest::newRow("ar_SA short") << "ar_SA" << QLocale("ar_SA").dateTimeFormat(QLocale::ShortFormat);
+ QTest::newRow("zh_CN long") << "zh_CN" << QLocale("zh_CN").dateTimeFormat();
+ QTest::newRow("zh_CN short") << "zh_CN" << QLocale("zh_CN").dateTimeFormat(QLocale::ShortFormat);
+}
+
+void tst_qdeclarativelocale::dateFromLocaleString()
+{
+ QFETCH(QString, locale);
+ QFETCH(QString, format);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("date.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QDateTime dt;
+ dt.setDate(QDate(2011, 10, 7));
+ dt.setTime(QTime(18, 53, 48, 345));
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QLocale l(locale);
+ QVariant val;
+ QMetaObject::invokeMethod(obj, "fromLocaleString", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(l.toString(dt, format))),
+ Q_ARG(QVariant, QVariant(format)));
+
+ QDateTime pd = l.toDateTime(l.toString(dt, format), format);
+ QCOMPARE(val.toDateTime(), pd);
+}
+
+void tst_qdeclarativelocale::dateFromLocaleDateString_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("format");
+
+ QTest::newRow("en_US 1") << "en_US" << "dddd, MMMM d, yyyy h:mm:ss AP";
+ QTest::newRow("en_US long") << "en_US" << QLocale("en_US").dateTimeFormat();
+ QTest::newRow("en_US short") << "en_US" << QLocale("en_US").dateTimeFormat(QLocale::ShortFormat);
+ QTest::newRow("de_DE long") << "de_DE" << QLocale("de_DE").dateTimeFormat();
+ QTest::newRow("de_DE short") << "de_DE" << QLocale("de_DE").dateTimeFormat(QLocale::ShortFormat);
+ QTest::newRow("ar_SA long") << "ar_SA" << QLocale("ar_SA").dateTimeFormat();
+ QTest::newRow("ar_SA short") << "ar_SA" << QLocale("ar_SA").dateTimeFormat(QLocale::ShortFormat);
+ QTest::newRow("zh_CN long") << "zh_CN" << QLocale("zh_CN").dateTimeFormat();
+ QTest::newRow("zh_CN short") << "zh_CN" << QLocale("zh_CN").dateTimeFormat(QLocale::ShortFormat);
+}
+
+void tst_qdeclarativelocale::dateFromLocaleDateString()
+{
+ QFETCH(QString, locale);
+ QFETCH(QString, format);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("date.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QDateTime dt;
+ dt.setDate(QDate(2011, 10, 7));
+ dt.setTime(QTime(18, 53, 48, 345));
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QLocale l(locale);
+ QVariant val;
+ QMetaObject::invokeMethod(obj, "fromLocaleDateString", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(l.toString(dt, format))),
+ Q_ARG(QVariant, QVariant(format)));
+
+ QDate pd = l.toDate(l.toString(dt, format), format);
+ QCOMPARE(val.toDate(), pd);
+}
+
+void tst_qdeclarativelocale::dateFromLocaleTimeString_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("format");
+
+ QTest::newRow("en_US 1") << "en_US" << "dddd, MMMM d, yyyy h:mm:ss AP";
+ QTest::newRow("en_US long") << "en_US" << QLocale("en_US").dateTimeFormat();
+ QTest::newRow("en_US short") << "en_US" << QLocale("en_US").dateTimeFormat(QLocale::ShortFormat);
+ QTest::newRow("de_DE long") << "de_DE" << QLocale("de_DE").dateTimeFormat();
+ QTest::newRow("de_DE short") << "de_DE" << QLocale("de_DE").dateTimeFormat(QLocale::ShortFormat);
+ QTest::newRow("ar_SA long") << "ar_SA" << QLocale("ar_SA").dateTimeFormat();
+ QTest::newRow("ar_SA short") << "ar_SA" << QLocale("ar_SA").dateTimeFormat(QLocale::ShortFormat);
+ QTest::newRow("zh_CN long") << "zh_CN" << QLocale("zh_CN").dateTimeFormat();
+ QTest::newRow("zh_CN short") << "zh_CN" << QLocale("zh_CN").dateTimeFormat(QLocale::ShortFormat);
+}
+
+void tst_qdeclarativelocale::dateFromLocaleTimeString()
+{
+ QFETCH(QString, locale);
+ QFETCH(QString, format);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("date.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QDateTime dt;
+ dt.setDate(QDate(2011, 10, 7));
+ dt.setTime(QTime(18, 53, 48, 345));
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QLocale l(locale);
+ QVariant val;
+ QMetaObject::invokeMethod(obj, "fromLocaleTimeString", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(l.toString(dt, format))),
+ Q_ARG(QVariant, QVariant(format)));
+
+ QTime pd = l.toTime(l.toString(dt, format), format);
+ QCOMPARE(val.toTime(), pd);
+}
+
+void tst_qdeclarativelocale::numberToLocaleString_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<char>("format");
+ QTest::addColumn<int>("prec");
+
+ QTest::newRow("en_US 1") << "en_US" << 'f' << 2;
+ QTest::newRow("en_US 2") << "en_US" << 'g' << 3;
+ QTest::newRow("en_US 3") << "en_US" << 'f' << 0;
+ QTest::newRow("en_US 4") << "en_US" << 'f' << -1;
+ QTest::newRow("de_DE 1") << "de_DE" << 'f' << 2;
+ QTest::newRow("de_DE 2") << "de_DE" << 'g' << 3;
+ QTest::newRow("ar_SA 1") << "ar_SA" << 'f' << 2;
+ QTest::newRow("ar_SA 2") << "ar_SA" << 'g' << 3;
+}
+
+void tst_qdeclarativelocale::numberToLocaleString()
+{
+ QFETCH(QString, locale);
+ QFETCH(char, format);
+ QFETCH(int, prec);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("number.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ double number = 2344423.3289;
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QLocale l(locale);
+ QVariant val;
+ QMetaObject::invokeMethod(obj, "toLocaleString", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(number)),
+ Q_ARG(QVariant, QVariant(QString(format))),
+ Q_ARG(QVariant, QVariant(prec)));
+
+ if (prec < 0) prec = 2;
+ QCOMPARE(val.toString(), l.toString(number, format, prec));
+}
+
+void tst_qdeclarativelocale::numberToLocaleCurrencyString_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("symbol");
+
+ QTest::newRow("en_US 1") << "en_US" << QString();
+ QTest::newRow("en_US 2") << "en_US" << "USD";
+ QTest::newRow("de_DE") << "de_DE" << QString();
+ QTest::newRow("ar_SA") << "ar_SA" << QString();
+ QTest::newRow("hi_IN") << "hi_IN" << QString();
+ QTest::newRow("zh_CN") << "zh_CN" << QString();
+ QTest::newRow("th_TH") << "th_TH" << QString();
+}
+
+void tst_qdeclarativelocale::numberToLocaleCurrencyString()
+{
+ QFETCH(QString, locale);
+ QFETCH(QString, symbol);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("number.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ double number = 2344423.3289;
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QLocale l(locale);
+ QVariant val;
+ QMetaObject::invokeMethod(obj, "toLocaleCurrencyString", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(number)),
+ Q_ARG(QVariant, QVariant(symbol)));
+
+ QCOMPARE(val.toString(), l.toCurrencyString(number, symbol));
+}
+
+void tst_qdeclarativelocale::numberFromLocaleString_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<double>("number");
+
+ QTest::newRow("en_US 1") << "en_US" << 1234567.2345;
+ QTest::newRow("en_US 2") << "en_US" << 0.234;
+ QTest::newRow("en_US 3") << "en_US" << 234.0;
+ QTest::newRow("de_DE") << "de_DE" << 1234567.2345;
+ QTest::newRow("ar_SA") << "ar_SA" << 1234567.2345;
+ QTest::newRow("hi_IN") << "hi_IN" << 1234567.2345;
+ QTest::newRow("zh_CN") << "zh_CN" << 1234567.2345;
+ QTest::newRow("th_TH") << "th_TH" << 1234567.2345;
+}
+
+void tst_qdeclarativelocale::numberFromLocaleString()
+{
+ QFETCH(QString, locale);
+ QFETCH(double, number);
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("number.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QLocale l(locale);
+ QString strNumber = l.toString(number, 'f');
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant(locale)));
+
+ QVariant val;
+ QMetaObject::invokeMethod(obj, "fromLocaleString", Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, val),
+ Q_ARG(QVariant, QVariant(strNumber)));
+
+ QCOMPARE(val.toDouble(), l.toDouble(strNumber));
+}
+
+void tst_qdeclarativelocale::numberConstToLocaleString()
+{
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("number.qml")));
+
+ QObject *obj = c.create();
+ QVERIFY(obj);
+
+ QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant("en_US")));
+
+ QLocale l("en_US");
+ QCOMPARE(obj->property("const1").toString(), l.toString(1234.56, 'f', 2));
+ QCOMPARE(obj->property("const2").toString(), l.toString(1234., 'f', 2));
+}
+
+QTEST_MAIN(tst_qdeclarativelocale)
+
+#include "tst_qdeclarativelocale.moc"