diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/common/qjsnumbercoercion.h | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 17 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 7 | ||||
-rw-r--r-- | src/qml/qml/qqmllocale.cpp | 524 | ||||
-rw-r--r-- | src/qml/qml/qqmllocale_p.h | 211 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypewrapper.cpp | 9 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypewrapper_p.h | 11 | ||||
-rw-r--r-- | src/quicktemplates/qquickspinbox.cpp | 6 |
8 files changed, 315 insertions, 475 deletions
diff --git a/src/qml/common/qjsnumbercoercion.h b/src/qml/common/qjsnumbercoercion.h index 53d587676d..569976454f 100644 --- a/src/qml/common/qjsnumbercoercion.h +++ b/src/qml/common/qjsnumbercoercion.h @@ -13,9 +13,6 @@ class QJSNumberCoercion { public: -#if QT_DEPRECATED_SINCE(6, 7) - - QT_DEPRECATED_VERSION_6_7 static constexpr bool isInteger(double d) { // Comparing d with itself checks for NaN and comparing d with the min and max values @@ -28,8 +25,6 @@ public: return equals(static_cast<int>(d), d); } -#endif - static constexpr bool isArrayIndex(double d) { if (d < 0 || !equals(d, d) || d > (std::numeric_limits<int>::max)()) { diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 7e61e0c22d..6f91712bb4 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1631,10 +1631,6 @@ static QVariant toVariant(const QV4::Value &value, QMetaType metaType, JSToQVari return str.at(0); return str; } -#if QT_CONFIG(qml_locale) - if (const QV4::QQmlLocaleData *ld = value.as<QV4::QQmlLocaleData>()) - return *ld->d()->locale; -#endif if (const QV4::DateObject *d = value.as<DateObject>()) { // NOTE: since we convert QTime to JS Date, // round trip will change the variant type (to QDateTime)! @@ -1864,10 +1860,6 @@ QV4::ReturnedValue ExecutionEngine::fromData( return QV4::JsonObject::fromJsonObject(this, *reinterpret_cast<const QJsonObject *>(ptr)); case QMetaType::QJsonArray: return QV4::JsonObject::fromJsonArray(this, *reinterpret_cast<const QJsonArray *>(ptr)); -#if QT_CONFIG(qml_locale) - case QMetaType::QLocale: - return QQmlLocale::wrap(this, *reinterpret_cast<const QLocale*>(ptr)); -#endif case QMetaType::QPixmap: case QMetaType::QImage: // Scarce value types @@ -2668,15 +2660,6 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi } break; } -#if QT_CONFIG(qml_locale) - case QMetaType::QLocale: { - if (const QV4::QQmlLocaleData *l = value.as<QQmlLocaleData>()) { - *reinterpret_cast<QLocale *>(data) = *l->d()->locale; - return true; - } - break; - } -#endif default: break; } diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 20f6a063de..c37031068c 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -251,13 +251,6 @@ static ReturnedValue loadProperty( property.readProperty(object, &v); return QV4::JsonObject::fromJsonArray(v4, v); } -#if QT_CONFIG(qml_locale) - case QMetaType::QLocale: { - QLocale v; - property.readProperty(object, &v); - return QQmlLocale::wrap(v4, v); - } -#endif case QMetaType::QStringList: return encodeSequence(QMetaSequence::fromContainer<QStringList>()); case QMetaType::QVariantList: diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index d0025324f4..50c460860b 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -13,13 +13,12 @@ #include <private/qv4dateobject_p.h> #include <private/qv4numberobject_p.h> #include <private/qv4stringobject_p.h> +#include <private/qqmlvaluetypewrapper_p.h> QT_BEGIN_NAMESPACE using namespace QV4; -DEFINE_OBJECT_VTABLE(QQmlLocaleData); - #define THROW_ERROR(string) \ do { \ return scope.engine->throwError(QString::fromUtf8(string)); \ @@ -27,13 +26,18 @@ DEFINE_OBJECT_VTABLE(QQmlLocaleData); #define GET_LOCALE_DATA_RESOURCE(OBJECT) \ - QV4::Scoped<QQmlLocaleData> r(scope, OBJECT.as<QQmlLocaleData>()); \ + QLocale *r = [&]() { \ + QV4::Scoped<QQmlValueTypeWrapper> r(scope, OBJECT.as<QQmlValueTypeWrapper>()); \ + return r ? r->cast<QLocale>() : nullptr; \ + }(); \ if (!r) \ THROW_ERROR("Not a valid Locale object") static bool isLocaleObject(const QV4::Value &val) { - return val.as<QQmlLocaleData>(); + if (const QV4::QQmlValueTypeWrapper *wrapper = val.as<QQmlValueTypeWrapper>()) + return wrapper->type() == QMetaType::fromType<QLocale>(); + return false; } //-------------- @@ -78,16 +82,16 @@ ReturnedValue QQmlDateExtension::method_toLocaleString(const QV4::FunctionObject if (argc == 2) { if (String *s = argv[1].stringValue()) { QString format = s->toQString(); - formattedDt = r->d()->locale->toString(dt, format); + formattedDt = r->toString(dt, format); } else if (argv[1].isNumber()) { quint32 intFormat = argv[1].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); - formattedDt = r->d()->locale->toString(dt, format); + formattedDt = r->toString(dt, format); } else { THROW_ERROR("Locale: Date.toLocaleString(): Invalid datetime format"); } } else { - formattedDt = r->d()->locale->toString(dt, enumFormat); + formattedDt = r->toString(dt, enumFormat); } RETURN_RESULT(scope.engine->newString(formattedDt)); @@ -122,16 +126,16 @@ ReturnedValue QQmlDateExtension::method_toLocaleTimeString(const QV4::FunctionOb if (argc == 2) { if (String *s = argv[1].stringValue()) { QString format = s->toQString(); - formattedTime = r->d()->locale->toString(time, format); + formattedTime = r->toString(time, format); } else if (argv[1].isNumber()) { quint32 intFormat = argv[1].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); - formattedTime = r->d()->locale->toString(time, format); + formattedTime = r->toString(time, format); } else { THROW_ERROR("Locale: Date.toLocaleTimeString(): Invalid time format"); } } else { - formattedTime = r->d()->locale->toString(time, enumFormat); + formattedTime = r->toString(time, enumFormat); } RETURN_RESULT(scope.engine->newString(formattedTime)); @@ -166,16 +170,16 @@ ReturnedValue QQmlDateExtension::method_toLocaleDateString(const QV4::FunctionOb if (argc == 2) { if (String *s = argv[1].stringValue()) { QString format = s->toQString(); - formattedDate = r->d()->locale->toString(date, format); + formattedDate = r->toString(date, format); } else if (argv[1].isNumber()) { quint32 intFormat = argv[1].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); - formattedDate = r->d()->locale->toString(date, format); + formattedDate = r->toString(date, format); } else { THROW_ERROR("Locale: Date.loLocaleDateString(): Invalid date format"); } } else { - formattedDate = r->d()->locale->toString(date, enumFormat); + formattedDate = r->toString(date, enumFormat); } RETURN_RESULT(scope.engine->newString(formattedDate)); @@ -205,16 +209,16 @@ ReturnedValue QQmlDateExtension::method_fromLocaleString(const QV4::FunctionObje if (argc == 3) { if (String *s = argv[2].stringValue()) { QString format = s->toQString(); - dt = r->d()->locale->toDateTime(dateString, format); + dt = r->toDateTime(dateString, format); } else if (argv[2].isNumber()) { quint32 intFormat = argv[2].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); - dt = r->d()->locale->toDateTime(dateString, format); + dt = r->toDateTime(dateString, format); } else { THROW_ERROR("Locale: Date.fromLocaleString(): Invalid datetime format"); } } else { - dt = r->d()->locale->toDateTime(dateString, enumFormat); + dt = r->toDateTime(dateString, enumFormat); } RETURN_RESULT(engine->newDateObject(dt)); @@ -247,16 +251,16 @@ ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(const QV4::Function if (argc == 3) { if (String *s = argv[2].stringValue()) { QString format = s->toQString(); - tm = r->d()->locale->toTime(dateString, format); + tm = r->toTime(dateString, format); } else if (argv[2].isNumber()) { quint32 intFormat = argv[2].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); - tm = r->d()->locale->toTime(dateString, format); + tm = r->toTime(dateString, format); } else { THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid datetime format"); } } else { - tm = r->d()->locale->toTime(dateString, enumFormat); + tm = r->toTime(dateString, enumFormat); } QDateTime dt; @@ -293,16 +297,16 @@ ReturnedValue QQmlDateExtension::method_fromLocaleDateString(const QV4::Function if (argc == 3) { if (String *s = argv[2].stringValue()) { QString format = s->toQString(); - dt = r->d()->locale->toDate(dateString, format); + dt = r->toDate(dateString, format); } else if (argv[2].isNumber()) { quint32 intFormat = argv[2].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); - dt = r->d()->locale->toDate(dateString, format); + dt = r->toDate(dateString, format); } else { THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid datetime format"); } } else { - dt = r->d()->locale->toDate(dateString, enumFormat); + dt = r->toDate(dateString, enumFormat); } RETURN_RESULT(engine->newDateObject(dt.startOfDay(QTimeZone::UTC))); @@ -363,7 +367,7 @@ QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(const QV4::Functio prec = argv[2].toInt32(); } - RETURN_RESULT(scope.engine->newString(r->d()->locale->toString(number, (char)format, prec))); + RETURN_RESULT(scope.engine->newString(r->toString(number, (char)format, prec))); } ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) @@ -392,7 +396,7 @@ ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(const QV4::Func symbol = argv[1].toQStringNoThrow(); } - RETURN_RESULT(scope.engine->newString(r->d()->locale->toCurrencyString(number, symbol))); + RETURN_RESULT(scope.engine->newString(r->toCurrencyString(number, symbol))); } ReturnedValue QQmlNumberExtension::method_fromLocaleString(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc) @@ -409,7 +413,7 @@ ReturnedValue QQmlNumberExtension::method_fromLocaleString(const QV4::FunctionOb THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments"); GET_LOCALE_DATA_RESOURCE(argv[0]); - locale = *r->d()->locale; + locale = *r; numberIdx = 1; } @@ -430,386 +434,161 @@ ReturnedValue QQmlNumberExtension::method_fromLocaleString(const QV4::FunctionOb //-------------- // Locale object -ReturnedValue QQmlLocaleData::method_get_firstDayOfWeek(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) +void QQmlLocaleValueType::formattedDataSize(QQmlV4Function *args) const { - QV4::Scope scope(b); - const QLocale *locale = getThisLocale(scope, thisObject); - if (!locale) - return Encode::undefined(); - int fdow = int(locale->firstDayOfWeek()); - if (fdow == 7) - fdow = 0; // Qt::Sunday = 7, but Sunday is 0 in JS Date - RETURN_RESULT(fdow); -} + QV4::Scope scope(args->v4engine()); + const auto doThrow = [&](const QString &message) { + args->setReturnValue(scope.engine->throwError(message)); + }; -ReturnedValue QQmlLocaleData::method_get_numberOptions(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { - QV4::Scope scope(b); - const QLocale *locale = getThisLocale(scope, thisObject); - if (!locale) - return Encode::undefined(); - int numberOptions = int(locale->numberOptions()); - RETURN_RESULT(numberOptions); -} + const int argc = args->length(); -ReturnedValue QQmlLocaleData::method_set_numberOptions(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { - QV4::Scope scope(b); - QLocale *locale = getThisLocale(scope, thisObject); - int const numberOptions = argc ? int(argv[0].toNumber()) : QLocale::DefaultNumberOptions; - locale->setNumberOptions(QLocale::NumberOptions {numberOptions}); - return Encode::undefined(); -} + if (argc < 1 || argc > 3) { + doThrow(QString::fromLatin1( + "Locale: formattedDataSize(): Expected 1-3 arguments, but received %1") + .arg(argc)); + return; + } -ReturnedValue QQmlLocaleData::method_get_formattedDataSize(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) -{ - QV4::Scope scope(b); - const QLocale *locale = getThisLocale(scope, thisObject); - if (!locale) - return Encode::undefined(); + QV4::ScopedValue arg0(scope, (*args)[0]); + bool mismatched0 = false; + if (!arg0->isNumber()) { + // ### Qt7: Throw an exception here, so that we don't have to handle mismatched0 below. + qWarning() << "Locale: formattedDataSize(): Invalid argument ('bytes' should be a number)"; + if (argc == 1) { + args->setReturnValue( + scope.engine->newString(locale.formattedDataSize(qint64(arg0->toInteger()))) + ->asReturnedValue()); + return; + } - if (argc < 1 || argc > 3) { - THROW_ERROR(QString::fromLatin1( - "Locale: formattedDataSize(): Expected 1-3 arguments, but received %1").arg(argc).toLatin1()); + mismatched0 = true; } - const qint64 bytes = static_cast<qint64>(argv[0].toInteger()); - if (argc == 1) - RETURN_RESULT(scope.engine->newString(locale->formattedDataSize(bytes))); + // Anything can be coerced to a number, for better or worse ... + Q_ASSERT(argc >= 2); - int precision = 0; - if (argc >= 2) { - if (!argv[1].isInteger()) - THROW_ERROR("Locale: formattedDataSize(): Invalid argument ('precision' must be an int)"); + QV4::ScopedValue arg1(scope, (*args)[1]); + if (!arg1->isInteger()) { + doThrow(QLatin1String( + "Locale: formattedDataSize(): Invalid argument ('precision' must be an int)")); + return; + } + + if (mismatched0) { + if (argc == 2) { + const QString result = locale.formattedDataSize( + qint64(arg0->toInteger()), arg1->integerValue()); + args->setReturnValue(scope.engine->newString(result)->asReturnedValue()); + return; + } - precision = argv[1].toInt32(); - if (argc == 2) - RETURN_RESULT(scope.engine->newString(locale->formattedDataSize(bytes, precision))); + QV4::ScopedValue arg2(scope, (*args)[2]); + if (arg2->isNumber()) { + const QString result = locale.formattedDataSize( + qint64(arg0->toInteger()), arg1->integerValue(), + QLocale::DataSizeFormats(arg2->integerValue())); + args->setReturnValue(scope.engine->newString(result)->asReturnedValue()); + return; + } } - // argc >= 3 - if (!argv[2].isNumber()) - THROW_ERROR("Locale: formattedDataSize(): Invalid argument ('format' must be DataSizeFormat)"); + Q_ASSERT(argc == 3); + Q_ASSERT(!QV4::ScopedValue(scope, (*args)[2])->isNumber()); - const quint32 intFormat = argv[2].toUInt32(); - const auto format = QLocale::DataSizeFormats(intFormat); - RETURN_RESULT(scope.engine->newString(locale->formattedDataSize(bytes, precision, format))); + doThrow(QLatin1String( + "Locale: formattedDataSize(): Invalid argument ('format' must be DataSizeFormat)")); } -ReturnedValue QQmlLocaleData::method_get_measurementSystem(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) +static QQmlLocale::DayOfWeek qtDayToQmlDay(Qt::DayOfWeek day) { - QV4::Scope scope(b); - const QLocale *locale = getThisLocale(scope, thisObject); - if (!locale) - return Encode::undefined(); - return QV4::Encode(locale->measurementSystem()); + return day == Qt::Sunday ? QQmlLocale::DayOfWeek::Sunday : QQmlLocale::DayOfWeek(day); } -ReturnedValue QQmlLocaleData::method_get_textDirection(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) +QQmlLocale::DayOfWeek QQmlLocaleValueType::firstDayOfWeek() const { - QV4::Scope scope(b); - const QLocale *locale = getThisLocale(scope, thisObject); - if (!locale) - return Encode::undefined(); - - return QV4::Encode(locale->textDirection()); + return qtDayToQmlDay(locale.firstDayOfWeek()); } -ReturnedValue QQmlLocaleData::method_get_weekDays(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) +QList<QQmlLocale::DayOfWeek> QQmlLocaleValueType::weekDays() const { - QV4::Scope scope(b); - const QLocale *locale = getThisLocale(scope, thisObject); - if (!locale) - return Encode::undefined(); - - QList<Qt::DayOfWeek> days = locale->weekdays(); - - QV4::ScopedArrayObject result(scope, scope.engine->newArrayObject()); - result->arrayReserve(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->arrayPut(i, QV4::Value::fromInt32(day)); - } - result->setArrayLengthUnchecked(days.size()); - - return result.asReturnedValue(); + const QList<Qt::DayOfWeek> days = locale.weekdays(); + QList<QQmlLocale::DayOfWeek> result; + result.reserve(days.size()); + for (Qt::DayOfWeek day : days) + result.append(qtDayToQmlDay(day)); + return result; } -ReturnedValue QQmlLocaleData::method_get_uiLanguages(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) +void QQmlLocaleValueType::toString(QQmlV4Function *args) const { - QV4::Scope scope(b); - const QLocale *locale = getThisLocale(scope, thisObject); - if (!locale) - return Encode::undefined(); - - QStringList langs = locale->uiLanguages(); - QV4::ScopedArrayObject result(scope, scope.engine->newArrayObject()); - result->arrayReserve(langs.size()); - QV4::ScopedValue v(scope); - for (int i = 0; i < langs.size(); ++i) - result->arrayPut(i, (v = scope.engine->newString(langs.at(i)))); + Scope scope(args->v4engine()); + const auto doThrow = [&](const QString &message) { + args->setReturnValue(scope.engine->throwError(message)); + }; - result->setArrayLengthUnchecked(langs.size()); + const int argc = args->length(); - return result.asReturnedValue(); -} - -ReturnedValue QQmlLocaleData::method_currencySymbol(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) -{ - QV4::Scope scope(b); - const QLocale *locale = getThisLocale(scope, thisObject); - if (!locale) - return Encode::undefined(); + // toString() + Q_ASSERT(argc > 0); - if (argc > 1) - THROW_ERROR("Locale: currencySymbol(): Invalid arguments"); - - QLocale::CurrencySymbolFormat format = QLocale::CurrencySymbol; - if (argc == 1) { - quint32 intFormat = argv[0].toNumber(); - format = QLocale::CurrencySymbolFormat(intFormat); + if (argc > 3) { + doThrow(QString::fromLatin1("Locale: toString(): Expected 1-3 arguments, but received %1") + .arg(argc)); + return; } - RETURN_RESULT(scope.engine->newString(locale->currencySymbol(format))); -} + QV4::ScopedValue arg0(scope, (*args)[0]); + if (arg0->isNumber()) { -#define LOCALE_FORMAT(FUNC) \ -ReturnedValue QQmlLocaleData::method_ ##FUNC (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { \ - QV4::Scope scope(b); \ - const QLocale *locale = getThisLocale(scope, thisObject); \ - if (!locale) \ - return Encode::undefined(); \ - if (argc > 1) \ - THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \ - QLocale::FormatType format = QLocale::LongFormat;\ - if (argc == 1) { \ - quint32 intFormat = argv[0].toUInt32(); \ - format = QLocale::FormatType(intFormat); \ - } \ - RETURN_RESULT(scope.engine->newString(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) \ -ReturnedValue QQmlLocaleData::method_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) {\ - Scope scope(b); \ - const QLocale *locale = getThisLocale(scope, thisObject); \ - if (!locale) \ - return Encode::undefined(); \ - if (argc < 1 || argc > 2) \ - THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \ - QLocale::FormatType enumFormat = QLocale::LongFormat; \ - int idx = argv[0].toInt32() + 1; \ - if (idx < 1 || idx > 12) \ - THROW_ERROR("Locale: Invalid month"); \ - QString name; \ - if (argc == 2) { \ - if (argv[1].isNumber()) { \ - quint32 intFormat = argv[1].toUInt32(); \ - QLocale::FormatType format = QLocale::FormatType(intFormat); \ - name = locale-> VARIABLE(idx, format); \ - } else { \ - THROW_ERROR("Locale: Invalid datetime format"); \ - } \ - } else { \ - name = locale-> VARIABLE(idx, enumFormat); \ - } \ - RETURN_RESULT(scope.engine->newString(name)); \ -} - -// 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date -#define LOCALE_FORMATTED_DAYNAME(VARIABLE) \ -ReturnedValue QQmlLocaleData::method_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) {\ - Scope scope(b); \ - const QLocale *locale = getThisLocale(scope, thisObject); \ - if (!locale) \ - return Encode::undefined(); \ - if (argc < 1 || argc > 2) \ - THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \ - QLocale::FormatType enumFormat = QLocale::LongFormat; \ - int idx = argv[0].toInt32(); \ - if (idx < 0 || idx > 7) \ - THROW_ERROR("Locale: Invalid day"); \ - if (idx == 0) idx = 7; \ - QString name; \ - if (argc == 2) { \ - if (argv[1].isNumber()) { \ - quint32 intFormat = argv[1].toUInt32(); \ - QLocale::FormatType format = QLocale::FormatType(intFormat); \ - name = locale-> VARIABLE(idx, format); \ - } else { \ - THROW_ERROR("Locale: Invalid datetime format"); \ - } \ - } else { \ - name = locale-> VARIABLE(idx, enumFormat); \ - } \ - RETURN_RESULT(scope.engine->newString(name)); \ -} - -LOCALE_FORMATTED_MONTHNAME(monthName) -LOCALE_FORMATTED_MONTHNAME(standaloneMonthName) -LOCALE_FORMATTED_DAYNAME(dayName) -LOCALE_FORMATTED_DAYNAME(standaloneDayName) + // toString(int) + // toString(double) + Q_ASSERT(argc != 1); -ReturnedValue QQmlLocaleData::method_toString(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) -{ - Scope scope(b); - const QLocale *locale = getThisLocale(scope, thisObject); - if (!locale) - return Encode::undefined(); + QV4::ScopedValue arg1(scope, (*args)[1]); + if (!arg1->isString()) { + doThrow(QLatin1String("Locale: the second argument to the toString overload " + "whose first argument is a double should be a char")); + return; + } - if (argc == 0) { - // As a special (undocumented) case, when called with no arguments, - // just forward to QDebug. This makes it consistent with other types - // in JS that can be converted to a string via toString(). - RETURN_RESULT(scope.engine->newString(QDebug::toString(*locale))); - } + // toString(double, const QString &) + // toString(double, const QString &, int) + Q_ASSERT(argc == 3); + Q_ASSERT(!QV4::ScopedValue(scope, (*args)[2])->isInteger()); - if (argc > 3) { - return scope.engine->throwError(QString::fromLatin1( - "Locale: toString(): Expected 1-3 arguments, but received %1").arg(argc)); + doThrow(QLatin1String("Locale: the third argument to the toString overload " + "whose first argument is a double should be an int")); + return; } - if (argv[0].isNumber()) { - if (argv[0].isInteger()) { - // toString(int) - RETURN_RESULT(scope.engine->newString(locale->toString(argv[0].toInt32()))); - } else { - // toString(double[, char][, int]) - const double number = argv[0].toNumber(); - if (argc == 1) - RETURN_RESULT(scope.engine->newString(locale->toString(number))); - - if (!argv[1].isString()) { - THROW_ERROR("Locale: the second argument to the toString overload " - "whose first argument is a double should be a char"); - } - const char format = argv[1].toQString().at(0).toLatin1(); - - switch (argc) { - case 2: - RETURN_RESULT(scope.engine->newString(locale->toString(number, format))); - case 3: - if (!argv[2].isInteger()) { - THROW_ERROR("Locale: the third argument to the toString overload " - "whose first argument is a double should be an int"); - } - - const int precision = argv[2].toInt32(); - RETURN_RESULT(scope.engine->newString(locale->toString(number, format, precision))); - } - } - } else if (const DateObject *dateObject = argv[0].as<DateObject>()) { - // toString(Date, string) or toString(Date[, FormatType]) + if (arg0->as<DateObject>()) { if (argc > 2) { - return scope.engine->throwError(QString::fromLatin1( - "Locale: the toString() overload that takes a Date as its first " - "argument expects 1 or 2 arguments, but received %1").arg(argc)); - } - - if (argc == 2 && argv[1].isString()) { - RETURN_RESULT(scope.engine->newString(locale->toString( - dateObject->toQDateTime(), argv[1].toQString()))); + doThrow(QString::fromLatin1( + "Locale: the toString() overload that takes a Date as its first " + "argument expects 1 or 2 arguments, but received %1").arg(argc)); + return; } - if (argc == 2 && !argv[1].isNumber()) { - THROW_ERROR("Locale: the second argument to the toString overloads whose " - "first argument is a Date should be a string or FormatType"); - } - - const QLocale::FormatType format = argc == 2 - ? QLocale::FormatType(argv[1].toNumber()) : QLocale::LongFormat; - RETURN_RESULT(scope.engine->newString(locale->toString(dateObject->toQDateTime(), format))); - } - - THROW_ERROR("Locale: toString() expects either an int, double, or Date as its first argument"); -} - -#define LOCALE_STRING_PROPERTY(VARIABLE) \ -ReturnedValue QQmlLocaleData::method_get_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) \ -{ \ - Scope scope(b); \ - const QLocale *locale = getThisLocale(scope, thisObject); \ - if (!locale) \ - return Encode::undefined(); \ - RETURN_RESULT(scope.engine->newString(locale-> VARIABLE()));\ -} + // toString(QDateTime) + Q_ASSERT(argc == 2); + QV4::ScopedValue arg1(scope, (*args)[1]); -LOCALE_STRING_PROPERTY(name) -LOCALE_STRING_PROPERTY(nativeLanguageName) -#if QT_DEPRECATED_SINCE(6, 6) -QT_IGNORE_DEPRECATIONS(LOCALE_STRING_PROPERTY(nativeCountryName)) -#endif -LOCALE_STRING_PROPERTY(nativeTerritoryName) -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 QV4LocaleDataDeletable : public QV4::ExecutionEngine::Deletable -{ -public: - QV4LocaleDataDeletable(QV4::ExecutionEngine *engine); - ~QV4LocaleDataDeletable(); + // toString(QDateTime, QString) + Q_ASSERT(!arg1->isString()); - QV4::PersistentValue prototype; -}; + // toString(QDateTime, QLocale::FormatType) + Q_ASSERT(!arg1->isNumber()); -QV4LocaleDataDeletable::QV4LocaleDataDeletable(QV4::ExecutionEngine *engine) -{ - QV4::Scope scope(engine); - QV4::Scoped<QV4::Object> o(scope, engine->newObject()); - - o->defineDefaultProperty(QStringLiteral("dateFormat"), QQmlLocaleData::method_dateFormat, 0); - o->defineDefaultProperty(QStringLiteral("standaloneDayName"), QQmlLocaleData::method_standaloneDayName, 0); - o->defineDefaultProperty(QStringLiteral("standaloneMonthName"), QQmlLocaleData::method_standaloneMonthName, 0); - o->defineDefaultProperty(QStringLiteral("dayName"), QQmlLocaleData::method_dayName, 0); - o->defineDefaultProperty(QStringLiteral("timeFormat"), QQmlLocaleData::method_timeFormat, 0); - o->defineDefaultProperty(QStringLiteral("monthName"), QQmlLocaleData::method_monthName, 0); - o->defineDefaultProperty(QStringLiteral("toString"), QQmlLocaleData::method_toString, 0); - o->defineDefaultProperty(QStringLiteral("currencySymbol"), QQmlLocaleData::method_currencySymbol, 0); - o->defineDefaultProperty(QStringLiteral("dateTimeFormat"), QQmlLocaleData::method_dateTimeFormat, 0); - o->defineDefaultProperty(QStringLiteral("formattedDataSize"), QQmlLocaleData::method_get_formattedDataSize, 0); - o->defineAccessorProperty(QStringLiteral("name"), QQmlLocaleData::method_get_name, nullptr); - o->defineAccessorProperty(QStringLiteral("positiveSign"), QQmlLocaleData::method_get_positiveSign, nullptr); - o->defineAccessorProperty(QStringLiteral("uiLanguages"), QQmlLocaleData::method_get_uiLanguages, nullptr); - o->defineAccessorProperty(QStringLiteral("firstDayOfWeek"), QQmlLocaleData::method_get_firstDayOfWeek, nullptr); - o->defineAccessorProperty(QStringLiteral("pmText"), QQmlLocaleData::method_get_pmText, nullptr); - o->defineAccessorProperty(QStringLiteral("percent"), QQmlLocaleData::method_get_percent, nullptr); - o->defineAccessorProperty(QStringLiteral("textDirection"), QQmlLocaleData::method_get_textDirection, nullptr); - o->defineAccessorProperty(QStringLiteral("weekDays"), QQmlLocaleData::method_get_weekDays, nullptr); - o->defineAccessorProperty(QStringLiteral("negativeSign"), QQmlLocaleData::method_get_negativeSign, nullptr); - o->defineAccessorProperty(QStringLiteral("groupSeparator"), QQmlLocaleData::method_get_groupSeparator, nullptr); - o->defineAccessorProperty(QStringLiteral("decimalPoint"), QQmlLocaleData::method_get_decimalPoint, nullptr); - o->defineAccessorProperty(QStringLiteral("nativeLanguageName"), QQmlLocaleData::method_get_nativeLanguageName, nullptr); -#if QT_DEPRECATED_SINCE(6, 6) - o->defineAccessorProperty(QStringLiteral("nativeCountryName"), QQmlLocaleData::method_get_nativeCountryName, nullptr); -#endif - o->defineAccessorProperty(QStringLiteral("nativeTerritoryName"), QQmlLocaleData::method_get_nativeTerritoryName, nullptr); - o->defineAccessorProperty(QStringLiteral("zeroDigit"), QQmlLocaleData::method_get_zeroDigit, nullptr); - o->defineAccessorProperty(QStringLiteral("amText"), QQmlLocaleData::method_get_amText, nullptr); - o->defineAccessorProperty(QStringLiteral("measurementSystem"), QQmlLocaleData::method_get_measurementSystem, nullptr); - o->defineAccessorProperty(QStringLiteral("exponential"), QQmlLocaleData::method_get_exponential, nullptr); - o->defineAccessorProperty(QStringLiteral("numberOptions"), QQmlLocaleData::method_get_numberOptions, QQmlLocaleData::method_set_numberOptions); - - prototype.set(engine, o); -} + doThrow(QLatin1String("Locale: the second argument to the toString overloads whose " + "first argument is a Date should be a string or FormatType")); + return; + } -QV4LocaleDataDeletable::~QV4LocaleDataDeletable() -{ + doThrow(QLatin1String("Locale: toString() expects either an int, double, " + "or Date as its first argument")); } -V4_DEFINE_EXTENSION(QV4LocaleDataDeletable, localeV4Data); - /*! \qmltype Locale //! \instantiates QQmlLocale @@ -904,21 +683,16 @@ V4_DEFINE_EXTENSION(QV4LocaleDataDeletable, localeV4Data); QV4::ReturnedValue QQmlLocale::locale(ExecutionEngine *engine, const QString &localeName) { - QLocale qlocale; - if (!localeName.isEmpty()) - qlocale = QLocale(localeName); - return wrap(engine, qlocale); -} + if (localeName.isEmpty()) { + return QQmlValueTypeWrapper::create( + engine, nullptr, &QQmlLocaleValueType::staticMetaObject, + QMetaType::fromType<QLocale>()); + } -QV4::ReturnedValue QQmlLocale::wrap(ExecutionEngine *v4, const QLocale &locale) -{ - QV4::Scope scope(v4); - QV4LocaleDataDeletable *d = localeV4Data(scope.engine); - QV4::Scoped<QQmlLocaleData> wrapper(scope, v4->memoryManager->allocate<QQmlLocaleData>()); - *wrapper->d()->locale = locale; - QV4::ScopedObject p(scope, d->prototype.value()); - wrapper->setPrototypeOf(p); - return wrapper.asReturnedValue(); + QLocale qlocale(localeName); + return QQmlValueTypeWrapper::create( + engine, &qlocale, &QQmlLocaleValueType::staticMetaObject, + QMetaType::fromType<QLocale>()); } void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine) diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h index b3700ef558..0fc9338015 100644 --- a/src/qml/qml/qqmllocale_p.h +++ b/src/qml/qml/qqmllocale_p.h @@ -75,81 +75,172 @@ namespace QQmlLocale Q_ENUM_NS(DayOfWeek) Q_QML_EXPORT QV4::ReturnedValue locale(QV4::ExecutionEngine *engine, const QString &localeName); - Q_QML_EXPORT QV4::ReturnedValue wrap(QV4::ExecutionEngine *engine, const QLocale &locale); Q_QML_EXPORT void registerStringLocaleCompare(QV4::ExecutionEngine *engine); Q_QML_EXPORT QV4::ReturnedValue method_localeCompare(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); }; -namespace QV4 { +struct DayOfWeekList +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QList<QQmlLocale::DayOfWeek>) + QML_SEQUENTIAL_CONTAINER(QQmlLocale::DayOfWeek) +}; + +class QQmlLocaleValueType +{ + QLocale locale; + + Q_PROPERTY(QQmlLocale::DayOfWeek firstDayOfWeek READ firstDayOfWeek CONSTANT) + Q_PROPERTY(QLocale::MeasurementSystem measurementSystem READ measurementSystem CONSTANT) + Q_PROPERTY(Qt::LayoutDirection textDirection READ textDirection CONSTANT) + Q_PROPERTY(QList<QQmlLocale::DayOfWeek> weekDays READ weekDays CONSTANT) + Q_PROPERTY(QStringList uiLanguages READ uiLanguages CONSTANT) + + Q_PROPERTY(QString name READ name CONSTANT) + Q_PROPERTY(QString nativeLanguageName READ nativeLanguageName CONSTANT) +#if QT_DEPRECATED_SINCE(6, 6) + Q_PROPERTY(QString nativeCountryName READ nativeCountryName CONSTANT) +#endif + Q_PROPERTY(QString nativeTerritoryName READ nativeTerritoryName CONSTANT) + Q_PROPERTY(QString decimalPoint READ decimalPoint CONSTANT) + Q_PROPERTY(QString groupSeparator READ groupSeparator CONSTANT) + Q_PROPERTY(QString percent READ percent CONSTANT) + Q_PROPERTY(QString zeroDigit READ zeroDigit CONSTANT) + Q_PROPERTY(QString negativeSign READ negativeSign CONSTANT) + Q_PROPERTY(QString positiveSign READ positiveSign CONSTANT) + Q_PROPERTY(QString exponential READ exponential CONSTANT) + Q_PROPERTY(QString amText READ amText CONSTANT) + Q_PROPERTY(QString pmText READ pmText CONSTANT) + + Q_PROPERTY(QLocale::NumberOptions numberOptions READ numberOptions WRITE setNumberOptions) + + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QLocale) + QML_EXTENDED(QQmlLocaleValueType) + QML_CONSTRUCTIBLE_VALUE + +public: + Q_INVOKABLE QQmlLocaleValueType(const QString &name) : locale(name) {} -namespace Heap { + Q_INVOKABLE QString currencySymbol( + QLocale::CurrencySymbolFormat format = QLocale::CurrencySymbol) const + { + return locale.currencySymbol(format); + } -struct QQmlLocaleData : Object { - inline void init() { locale = new QLocale; } - void destroy() { - delete locale; - Object::destroy(); + Q_INVOKABLE QString dateTimeFormat(QLocale::FormatType format = QLocale::LongFormat) const + { + return locale.dateTimeFormat(format); } - QLocale *locale; -}; -} + Q_INVOKABLE QString timeFormat(QLocale::FormatType format = QLocale::LongFormat) const + { + return locale.timeFormat(format); + } -struct QQmlLocaleData : public QV4::Object -{ - V4_OBJECT2(QQmlLocaleData, Object) - V4_NEEDS_DESTROY - - static QLocale *getThisLocale(QV4::Scope &scope, const QV4::Value *thisObject) { - const QV4::Object *o = thisObject->as<Object>(); - const QQmlLocaleData *data = o ? o->as<QQmlLocaleData>() : nullptr; - if (!data) { - scope.engine->throwTypeError(); - return nullptr; - } - return data->d()->locale; + Q_INVOKABLE QString dateFormat(QLocale::FormatType format = QLocale::LongFormat) const + { + return locale.dateFormat(format); + } + + Q_INVOKABLE QString monthName(int index, QLocale::FormatType format = QLocale::LongFormat) const + { + // +1 added to idx because JS is 0-based, whereas QLocale months begin at 1. + return locale.monthName(index + 1, format); + } + + Q_INVOKABLE QString standaloneMonthName( + int index, QLocale::FormatType format = QLocale::LongFormat) const + { + // +1 added to idx because JS is 0-based, whereas QLocale months begin at 1. + return locale.standaloneMonthName(index + 1, format); } - static QV4::ReturnedValue method_currencySymbol(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_dateTimeFormat(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_timeFormat(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_dateFormat(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_monthName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_standaloneMonthName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_dayName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_standaloneDayName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_toString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - - static QV4::ReturnedValue method_get_firstDayOfWeek(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_measurementSystem(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_textDirection(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_weekDays(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_uiLanguages(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - - static QV4::ReturnedValue method_get_name(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_nativeLanguageName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + Q_INVOKABLE QString dayName(int index, QLocale::FormatType format = QLocale::LongFormat) const + { + // 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date + return locale.dayName(index == 0 ? 7 : index, format); + } + + Q_INVOKABLE QString standaloneDayName( + int index, QLocale::FormatType format = QLocale::LongFormat) const + { + // 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date + return locale.standaloneDayName(index == 0 ? 7 : index, format); + } + + Q_INVOKABLE void formattedDataSize(QQmlV4Function *args) const; + Q_INVOKABLE QString formattedDataSize( + double bytes, int precision = 2, + QLocale::DataSizeFormats format = QLocale::DataSizeIecFormat) const + { + return locale.formattedDataSize( + qint64(QV4::Value::toInteger(bytes)), precision, format); + } + + Q_INVOKABLE void toString(QQmlV4Function *args) const; + + // As a special (undocumented) case, when called with no arguments, + // just forward to QDebug. This makes it consistent with other types + // in JS that can be converted to a string via toString(). + Q_INVOKABLE QString toString() const { return QDebug::toString(locale); } + + Q_INVOKABLE QString toString(int i) const { return locale.toString(i); } + Q_INVOKABLE QString toString(double f) const + { + return QJSNumberCoercion::isInteger(f) ? toString(int(f)) : locale.toString(f); + } + Q_INVOKABLE QString toString(double f, const QString &format, int precision = 6) const + { + // Lacking a char type, we have to use QString here + return format.length() < 1 + ? QString() + : locale.toString(f, format.at(0).toLatin1(), precision); + } + Q_INVOKABLE QString toString(const QDateTime &dateTime, const QString &format) const + { + return locale.toString(dateTime, format); + } + Q_INVOKABLE QString toString( + const QDateTime &dateTime, QLocale::FormatType format = QLocale::LongFormat) const + { + return locale.toString(dateTime, format); + } + + QQmlLocale::DayOfWeek firstDayOfWeek() const; + QLocale::MeasurementSystem measurementSystem() const { return locale.measurementSystem(); } + Qt::LayoutDirection textDirection() const { return locale.textDirection(); } + QList<QQmlLocale::DayOfWeek> weekDays() const; + QStringList uiLanguages() const { return locale.uiLanguages(); } + + QString name() const { return locale.name(); } + QString nativeLanguageName() const { return locale.nativeLanguageName(); } #if QT_DEPRECATED_SINCE(6, 6) - static QV4::ReturnedValue method_get_nativeCountryName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + QString nativeCountryName() const + { + QT_IGNORE_DEPRECATIONS(return locale.nativeCountryName();) + } #endif - static QV4::ReturnedValue method_get_nativeTerritoryName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_decimalPoint(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_groupSeparator(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_percent(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_zeroDigit(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_negativeSign(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_positiveSign(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_exponential(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_amText(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_get_pmText(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - - static QV4::ReturnedValue method_get_numberOptions(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - static QV4::ReturnedValue method_set_numberOptions(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); - - static QV4::ReturnedValue method_get_formattedDataSize(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + QString nativeTerritoryName() const { return locale.nativeTerritoryName(); } + QString decimalPoint() const { return locale.decimalPoint(); } + QString groupSeparator() const { return locale.groupSeparator(); } + QString percent() const { return locale.percent(); } + QString zeroDigit() const { return locale.zeroDigit(); } + QString negativeSign() const { return locale.negativeSign(); } + QString positiveSign() const { return locale.positiveSign(); } + QString exponential() const { return locale.exponential(); } + QString amText() const { return locale.amText(); } + QString pmText() const { return locale.pmText(); } + + QLocale::NumberOptions numberOptions() const { return locale.numberOptions(); } + void setNumberOptions(const QLocale::NumberOptions &numberOptions) + { + locale.setNumberOptions(numberOptions); + } }; -} - QT_END_NAMESPACE #endif diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index da3c2bfe2c..e0d684e377 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -339,12 +339,6 @@ static ReturnedValue getGadgetProperty(ExecutionEngine *engine, time, valueTypeWrapper, index, referenceFlags(metaObject, index)); }; -#if QT_CONFIG(qml_locale) - const auto wrapLocale = [engine](const QLocale &locale) { - return QQmlLocale::wrap(engine, locale); - }; -#endif - #define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \ case metatype: { \ cpptype v; \ @@ -397,9 +391,6 @@ static ReturnedValue getGadgetProperty(ExecutionEngine *engine, VALUE_TYPE_LOAD(QMetaType::QJsonValue, QJsonValue, wrapJsonValue); VALUE_TYPE_LOAD(QMetaType::QJsonObject, QJsonObject, wrapJsonObject); VALUE_TYPE_LOAD(QMetaType::QJsonArray, QJsonArray, wrapJsonArray); -#if QT_CONFIG(qml_locale) - VALUE_TYPE_LOAD(QMetaType::QLocale, QLocale, wrapLocale); -#endif case QMetaType::QPixmap: case QMetaType::QImage: { QVariant v(metaType); diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h index df173e6325..5b3894a07f 100644 --- a/src/qml/qml/qqmlvaluetypewrapper_p.h +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -120,6 +120,17 @@ public: ExecutionEngine *engine, const void *, const QMetaObject *metaObject, QMetaType type); QVariant toVariant() const; + + template<typename ValueType> + ValueType *cast() + { + if (QMetaType::fromType<ValueType>() != d()->metaType()) + return nullptr; + if (d()->isReference() && !readReferenceValue()) + return nullptr; + return static_cast<ValueType *>(d()->gadgetPtr()); + } + bool toGadget(void *data) const; bool isEqual(const QVariant& value) const; int typeId() const; diff --git a/src/quicktemplates/qquickspinbox.cpp b/src/quicktemplates/qquickspinbox.cpp index a76a06076c..5dce7809a5 100644 --- a/src/quicktemplates/qquickspinbox.cpp +++ b/src/quicktemplates/qquickspinbox.cpp @@ -437,7 +437,8 @@ QString QQuickSpinBoxPrivate::evaluateTextFromValue(int val) const QJSValue loc; #if QT_CONFIG(qml_locale) QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine); - loc = QJSValuePrivate::fromReturnedValue(QQmlLocale::wrap(v4, locale)); + loc = QJSValuePrivate::fromReturnedValue( + v4->fromData(QMetaType::fromType<QLocale>(), &locale)); #endif text = textFromValue.call(QJSValueList() << val << loc).toString(); } else { @@ -455,7 +456,8 @@ int QQuickSpinBoxPrivate::evaluateValueFromText(const QString &text) const QJSValue loc; #if QT_CONFIG(qml_locale) QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine); - loc = QJSValuePrivate::fromReturnedValue(QQmlLocale::wrap(v4, locale)); + loc = QJSValuePrivate::fromReturnedValue( + v4->fromData(QMetaType::fromType<QLocale>(), &locale)); #endif value = valueFromText.call(QJSValueList() << text << loc).toInt(); } else { |