1/*
2 SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include <KCountry>
8#include <KCountrySubdivision>
9#include <KTimeZone>
10
11#include <QCoreApplication>
12#include <QQmlContext>
13#include <QQmlEngine>
14#include <QQmlExtensionPlugin>
15
16#include <cstring>
17
18class KI18nLocaleDataQmlPlugin : public QQmlExtensionPlugin
19{
20 Q_OBJECT
21 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
22public:
23 void registerTypes(const char *uri) override;
24};
25
26// return "undefined" for invalid objects, so JS conditionals work as expected
27template<typename T>
28static QJSValue toJsValue(T value, QJSEngine *engine)
29{
30 return value.isValid() ? engine->toScriptValue(value) : QJSValue(QJSValue::UndefinedValue);
31}
32
33class KCountryFactory
34{
35 Q_GADGET
36 Q_PROPERTY(QList<KCountry> allCountries READ allCountries)
37public:
38 Q_INVOKABLE QJSValue fromAlpha2(const QString &code) const
39 {
40 return toJsValue(value: KCountry::fromAlpha2(alpha2Code: code), engine: m_engine);
41 }
42 Q_INVOKABLE QJSValue fromAlpha3(const QString &code) const
43 {
44 return toJsValue(value: KCountry::fromAlpha3(alpha3Code: code), engine: m_engine);
45 }
46 Q_INVOKABLE QJSValue fromName(const QString &name) const
47 {
48 return toJsValue(value: KCountry::fromName(name), engine: m_engine);
49 }
50 Q_INVOKABLE QJSValue fromLocation(double latitude, double longitude) const
51 {
52 return toJsValue(value: KCountry::fromLocation(latitude, longitude), engine: m_engine);
53 }
54
55 QJSEngine *m_engine = nullptr;
56
57private:
58 QList<KCountry> allCountries() const
59 {
60 return KCountry::allCountries();
61 }
62};
63
64class KCountrySubdivisionFactory
65{
66 Q_GADGET
67public:
68 Q_INVOKABLE QJSValue fromCode(const QString &code) const
69 {
70 return toJsValue(value: KCountrySubdivision::fromCode(code), engine: m_engine);
71 }
72 Q_INVOKABLE QJSValue fromLocation(double latitude, double longitude) const
73 {
74 return toJsValue(value: KCountrySubdivision::fromLocation(latitude, longitude), engine: m_engine);
75 }
76
77 QJSEngine *m_engine = nullptr;
78};
79
80class KTimeZoneWrapper
81{
82 Q_GADGET
83public:
84 Q_INVOKABLE QJSValue fromLocation(double latitude, double longitude) const
85 {
86 const auto tzId = KTimeZone::fromLocation(latitude, longitude);
87 return tzId ? QString::fromUtf8(utf8: tzId) : QJSValue(QJSValue::UndefinedValue);
88 }
89
90 Q_INVOKABLE QJSValue country(const QString &tzId) const
91 {
92 return toJsValue(value: KTimeZone::country(ianaId: tzId.toUtf8()), engine: m_engine);
93 }
94
95 QJSEngine *m_engine = nullptr;
96};
97
98void KI18nLocaleDataQmlPlugin::registerTypes(const char *uri)
99{
100 Q_ASSERT(std::strcmp(uri, "org.kde.i18n.localeData") == 0);
101
102 qRegisterMetaType<KCountry>();
103 qRegisterMetaType<KCountrySubdivision>();
104 qRegisterMetaType<QList<KCountrySubdivision>>();
105
106 // HACK qmlplugindump chokes on gadget singletons, to the point of breaking ecm_find_qmlmodule()
107 if (QCoreApplication::applicationName() != QLatin1String("qmlplugindump")) {
108 qmlRegisterSingletonType(uri, versionMajor: 1, versionMinor: 0, typeName: "Country", callback: [](QQmlEngine *, QJSEngine *engine) -> QJSValue {
109 KCountryFactory factory;
110 factory.m_engine = engine;
111 return engine->toScriptValue(value: factory);
112 });
113 qmlRegisterSingletonType(uri, versionMajor: 1, versionMinor: 0, typeName: "CountrySubdivision", callback: [](QQmlEngine *, QJSEngine *engine) -> QJSValue {
114 KCountrySubdivisionFactory factory;
115 factory.m_engine = engine;
116 return engine->toScriptValue(value: factory);
117 });
118 qmlRegisterSingletonType(uri, versionMajor: 1, versionMinor: 0, typeName: "TimeZone", callback: [](QQmlEngine *, QJSEngine *engine) -> QJSValue {
119 KTimeZoneWrapper wrapper;
120 wrapper.m_engine = engine;
121 return engine->toScriptValue(value: wrapper);
122 });
123 }
124}
125
126#include "ki18nlocaledataqmlplugin.moc"
127

source code of ki18n/src/localedata-qml/ki18nlocaledataqmlplugin.cpp