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 | /*! |
34 | * \qmltype Country |
35 | * \inqmlmodule org.kde.i18n.localeData |
36 | */ |
37 | class KCountryFactory |
38 | { |
39 | Q_GADGET |
40 | /*! |
41 | * \qmlproperty list<KCountry> Country::allCountries |
42 | */ |
43 | Q_PROPERTY(QList<KCountry> allCountries READ allCountries) |
44 | public: |
45 | /*! |
46 | * \qmlmethod KCountry Country::fromAlpha2(string code) |
47 | */ |
48 | Q_INVOKABLE QJSValue fromAlpha2(const QString &code) const |
49 | { |
50 | return toJsValue(value: KCountry::fromAlpha2(alpha2Code: code), engine: m_engine); |
51 | } |
52 | |
53 | /*! |
54 | * \qmlmethod KCountry Country::fromAlpha3(string code) |
55 | */ |
56 | Q_INVOKABLE QJSValue fromAlpha3(const QString &code) const |
57 | { |
58 | return toJsValue(value: KCountry::fromAlpha3(alpha3Code: code), engine: m_engine); |
59 | } |
60 | |
61 | /*! |
62 | * \qmlmethod KCountry Country::fromName(string name) |
63 | */ |
64 | Q_INVOKABLE QJSValue fromName(const QString &name) const |
65 | { |
66 | return toJsValue(value: KCountry::fromName(name), engine: m_engine); |
67 | } |
68 | |
69 | /*! |
70 | * \qmlmethod KCountry Country::fromLocation(real latitude, real longitude) |
71 | */ |
72 | Q_INVOKABLE QJSValue fromLocation(double latitude, double longitude) const |
73 | { |
74 | return toJsValue(value: KCountry::fromLocation(latitude, longitude), engine: m_engine); |
75 | } |
76 | |
77 | QJSEngine *m_engine = nullptr; |
78 | |
79 | private: |
80 | QList<KCountry> allCountries() const |
81 | { |
82 | return KCountry::allCountries(); |
83 | } |
84 | }; |
85 | |
86 | /*! |
87 | * \qmltype CountrySubdivision |
88 | * \inqmlmodule org.kde.i18n.localeData |
89 | */ |
90 | class KCountrySubdivisionFactory |
91 | { |
92 | Q_GADGET |
93 | public: |
94 | /*! |
95 | * \qmlmethod KCountrySubdivision CountrySubdivision::fromCode(string code) |
96 | */ |
97 | Q_INVOKABLE QJSValue fromCode(const QString &code) const |
98 | { |
99 | return toJsValue(value: KCountrySubdivision::fromCode(code), engine: m_engine); |
100 | } |
101 | |
102 | /*! |
103 | * \qmlmethod KCountrySubdivision CountrySubdivision::fromLocation(real latitude, real longitude) |
104 | */ |
105 | Q_INVOKABLE QJSValue fromLocation(double latitude, double longitude) const |
106 | { |
107 | return toJsValue(value: KCountrySubdivision::fromLocation(latitude, longitude), engine: m_engine); |
108 | } |
109 | |
110 | QJSEngine *m_engine = nullptr; |
111 | }; |
112 | |
113 | /*! |
114 | * \qmltype TimeZone |
115 | * \inqmlmodule org.kde.i18n.localeData |
116 | */ |
117 | class KTimeZoneWrapper |
118 | { |
119 | Q_GADGET |
120 | public: |
121 | /*! |
122 | * \qmlmethod KTimeZone TimeZone::fromLocation(real latitude, real longitude) |
123 | */ |
124 | Q_INVOKABLE QJSValue fromLocation(double latitude, double longitude) const |
125 | { |
126 | const auto tzId = KTimeZone::fromLocation(latitude, longitude); |
127 | return tzId ? QString::fromUtf8(utf8: tzId) : QJSValue(QJSValue::UndefinedValue); |
128 | } |
129 | |
130 | /*! |
131 | * \qmlmethod KTimeZone TimeZone::country(string tzId) |
132 | */ |
133 | Q_INVOKABLE QJSValue country(const QString &tzId) const |
134 | { |
135 | return toJsValue(value: KTimeZone::country(ianaId: tzId.toUtf8()), engine: m_engine); |
136 | } |
137 | |
138 | QJSEngine *m_engine = nullptr; |
139 | }; |
140 | |
141 | void KI18nLocaleDataQmlPlugin::registerTypes(const char *uri) |
142 | { |
143 | Q_ASSERT(std::strcmp(uri, "org.kde.i18n.localeData" ) == 0); |
144 | |
145 | qRegisterMetaType<KCountry>(); |
146 | qRegisterMetaType<KCountrySubdivision>(); |
147 | qRegisterMetaType<QList<KCountrySubdivision>>(); |
148 | |
149 | // HACK qmlplugindump chokes on gadget singletons, to the point of breaking ecm_find_qmlmodule() |
150 | if (QCoreApplication::applicationName() != QLatin1String("qmlplugindump" )) { |
151 | qmlRegisterSingletonType(uri, versionMajor: 1, versionMinor: 0, typeName: "Country" , callback: [](QQmlEngine *, QJSEngine *engine) -> QJSValue { |
152 | KCountryFactory factory; |
153 | factory.m_engine = engine; |
154 | return engine->toScriptValue(value: factory); |
155 | }); |
156 | qmlRegisterSingletonType(uri, versionMajor: 1, versionMinor: 0, typeName: "CountrySubdivision" , callback: [](QQmlEngine *, QJSEngine *engine) -> QJSValue { |
157 | KCountrySubdivisionFactory factory; |
158 | factory.m_engine = engine; |
159 | return engine->toScriptValue(value: factory); |
160 | }); |
161 | qmlRegisterSingletonType(uri, versionMajor: 1, versionMinor: 0, typeName: "TimeZone" , callback: [](QQmlEngine *, QJSEngine *engine) -> QJSValue { |
162 | KTimeZoneWrapper wrapper; |
163 | wrapper.m_engine = engine; |
164 | return engine->toScriptValue(value: wrapper); |
165 | }); |
166 | } |
167 | } |
168 | |
169 | #include "ki18nlocaledataqmlplugin.moc" |
170 | |