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 | |
18 | class KI18nLocaleDataQmlPlugin : public QQmlExtensionPlugin |
19 | { |
20 | Q_OBJECT |
21 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" ) |
22 | public: |
23 | void registerTypes(const char *uri) override; |
24 | }; |
25 | |
26 | // return "undefined" for invalid objects, so JS conditionals work as expected |
27 | template<typename T> |
28 | static QJSValue toJsValue(T value, QJSEngine *engine) |
29 | { |
30 | return value.isValid() ? engine->toScriptValue(value) : QJSValue(QJSValue::UndefinedValue); |
31 | } |
32 | |
33 | class KCountryFactory |
34 | { |
35 | Q_GADGET |
36 | Q_PROPERTY(QList<KCountry> allCountries READ allCountries) |
37 | public: |
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 | |
57 | private: |
58 | QList<KCountry> allCountries() const |
59 | { |
60 | return KCountry::allCountries(); |
61 | } |
62 | }; |
63 | |
64 | class KCountrySubdivisionFactory |
65 | { |
66 | Q_GADGET |
67 | public: |
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 | |
80 | class KTimeZoneWrapper |
81 | { |
82 | Q_GADGET |
83 | public: |
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 | |
98 | void 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 | |