wasm: Add QLocale backend

This is a simple backend based on navigator.languages,
which gives us a prioritized list of languages in the
form '["en-US", "zh-CN", "ja-JP"]'.

Use this to implement QSystemLocale::query() for UILanguages
and QSystemLocale::fallbackLocale().

Register an event handler for the native QWindow:languagechange
event in the QSystemLocale constructor. This event handler
stays active for the lifetime of the QSystemLocale object.

Task-number: QTBUG-116613
Change-Id: Ibd176748377e891b63a3f1d57605af0c2a49edb3
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Morten Sørvig 2023-10-12 15:26:05 +02:00
parent adf39eff44
commit 63fc3175b4
4 changed files with 78 additions and 1 deletions

View File

@ -797,7 +797,7 @@ qt_internal_extend_target(Core CONDITION APPLE
text/qlocale_mac.mm
)
qt_internal_extend_target(Core CONDITION UNIX AND NOT APPLE
qt_internal_extend_target(Core CONDITION UNIX AND NOT APPLE AND NOT WASM
SOURCES
text/qlocale_unix.cpp
)
@ -807,6 +807,11 @@ qt_internal_extend_target(Core CONDITION WIN32
text/qlocale_win.cpp
)
qt_internal_extend_target(Core CONDITION WASM
SOURCES
text/qlocale_wasm.cpp
)
# On MS-Win, clang has two flavors, one of which immitates MSVC (so claims to be it)
qt_internal_extend_target(Core CONDITION MSVC
LIBRARIES

View File

@ -720,6 +720,17 @@ QSystemLocale::QSystemLocale() : next(_systemLocale)
_systemLocale = this;
systemLocaleData.m_language_id = 0;
#ifdef Q_OS_WASM
onLanguageChanged = std::make_unique<qstdweb::EventCallback>(
emscripten::val::global("window"), "languagechange", [](emscripten::val) {
systemLocaleData.m_language_id = 0;
QEvent languageChangeEvent(QEvent::LanguageChange);
QCoreApplication::sendEvent(qApp, &languageChangeEvent);
QEvent localeChangeEvent(QEvent::LocaleChange);
QCoreApplication::sendEvent(qApp, &localeChangeEvent);
});
#endif
}
/*!

View File

@ -25,6 +25,9 @@
#include <QtCore/qstring.h>
#include <QtCore/qvariant.h>
#include <QtCore/qvarlengtharray.h>
#ifdef Q_OS_WASM
#include <private/qstdweb_p.h>
#endif
#include <limits>
#include <cmath>
@ -103,6 +106,10 @@ struct QLocaleData;
class Q_CORE_EXPORT QSystemLocale
{
QSystemLocale *next = nullptr; // Maintains a stack.
#ifdef Q_OS_WASM
std::unique_ptr<qstdweb::EventCallback> onLanguageChanged;
#endif
public:
QSystemLocale();
virtual ~QSystemLocale();

View File

@ -0,0 +1,54 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qlocale_p.h"
#include <emscripten/val.h>
#include <string>
#include <vector>
QT_BEGIN_NAMESPACE
#ifndef QT_NO_SYSTEMLOCALE
namespace {
QStringList navigatorLanguages()
{
using emscripten::val;
const val navigator = val::global("navigator");
const auto languages = emscripten::vecFromJSArray<std::string>(navigator["languages"]);
QStringList qtLanguages;
for (const std::string& language : languages)
qtLanguages.append(QString::fromStdString(language));
return qtLanguages;
}
}
QVariant QSystemLocale::query(QueryType query, QVariant in) const
{
Q_UNUSED(in);
switch (query) {
case QSystemLocale::UILanguages:
return QVariant(navigatorLanguages());
default:
break;
}
return QVariant();
}
QLocale QSystemLocale::fallbackLocale() const
{
const QStringList languages = navigatorLanguages();
if (languages.isEmpty())
return QLocale(u"en-US");
return QLocale(languages[0]);
}
#endif // QT_NO_SYSTEMLOCALE
QT_END_NAMESPACE