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
33/*!
34 * \qmltype Country
35 * \inqmlmodule org.kde.i18n.localeData
36 */
37class KCountryFactory
38{
39 Q_GADGET
40 /*!
41 * \qmlproperty list<KCountry> Country::allCountries
42 */
43 Q_PROPERTY(QList<KCountry> allCountries READ allCountries)
44public:
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
79private:
80 QList<KCountry> allCountries() const
81 {
82 return KCountry::allCountries();
83 }
84};
85
86/*!
87 * \qmltype CountrySubdivision
88 * \inqmlmodule org.kde.i18n.localeData
89 */
90class KCountrySubdivisionFactory
91{
92 Q_GADGET
93public:
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 */
117class KTimeZoneWrapper
118{
119 Q_GADGET
120public:
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
141void 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

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