KUnitConversion

currency.cpp
1/*
2 * SPDX-FileCopyrightText: 2009 Petri Damstén <damu@iki.fi>
3 * SPDX-FileCopyrightText: 2014 John Layt <jlayt@kde.org>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
8#include "currency_p.h"
9#include "kunitconversion_debug.h"
10#include "unit_p.h"
11#include "unitcategory.h"
12#include <KLocalizedString>
13#include <QDateTime>
14#include <QDir>
15#include <QFileInfo>
16#include <QLocale>
17#include <QNetworkAccessManager>
18#include <QNetworkInterface>
19#include <QNetworkReply>
20#include <QNetworkRequest>
21#include <QSaveFile>
22#include <QStandardPaths>
23#include <QXmlStreamReader>
24
25using namespace std::chrono_literals;
26
27namespace KUnitConversion
28{
29static const char URL[] = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
30
31static QString cacheLocation()
32{
33#ifndef Q_OS_ANDROID
34 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/libkunitconversion/currency.xml");
35#else
36 return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/libkunitconversion/currency.xml");
37#endif
38}
39
40class CurrencyCategoryPrivate : public UnitCategoryPrivate
41{
42public:
43 CurrencyCategoryPrivate(CategoryId id, const QString &name, const QString &description)
44 : UnitCategoryPrivate(id, name, description)
45 {
46 }
47
48 Value convert(const Value &value, const Unit &toUnit) override;
49 bool hasOnlineConversionTable() const override;
50 UpdateJob* syncConversionTable(std::chrono::seconds updateSkipSeconds) override;
51
52 QNetworkReply *m_currentReply = nullptr;
53 bool readConversionTable(const QString &cacheLocation);
54 bool m_initialized{false}; //!< indicates if units are prepared from currency table
55};
56
57bool CurrencyCategoryPrivate::hasOnlineConversionTable() const
58{
59 return true;
60}
61
62UnitCategory Currency::makeCategory()
63{
64 auto c = UnitCategoryPrivate::makeCategory(new CurrencyCategoryPrivate(CurrencyCategory, i18n("Currency"), i18n("From ECB")));
65 auto d = UnitCategoryPrivate::get(c);
66 KLocalizedString symbolString = ki18nc("%1 value, %2 unit symbol (currency)", "%1 %2");
67
68 // Static rates
69 d->addDefaultUnit(UnitPrivate::makeUnit(CurrencyCategory,
70 Eur,
71 1.0,
72 QStringLiteral("EUR"),
73 i18nc("currency name", "Euro"),
74 i18nc("EUR Euro - unit synonyms for matching user input", "euro;euros") + QStringLiteral(";EUR;") + QStringLiteral("€")
75 + QLatin1Char(';') + i18nc("currency name", "Euro"),
76 symbolString,
77 ki18nc("amount in units (real)", "%1 euros"),
78 ki18ncp("amount in units (integer)", "%1 euro", "%1 euros")));
79
80 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
81 Ats,
82 0.0726728,
83 QStringLiteral("ATS"),
84 i18nc("currency name", "Austrian Schilling"),
85 i18nc("ATS Austrian Schilling - unit synonyms for matching user input", "schilling;schillings") + QStringLiteral(";ATS;")
86 + QLocale::territoryToString(QLocale::Austria) + QLatin1Char(';') + i18nc("currency name", "Austrian Schilling"),
87 symbolString,
88 ki18nc("amount in units (real)", "%1 schillings"),
89 ki18ncp("amount in units (integer)", "%1 schilling", "%1 schillings")));
90
91 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
92 Bef,
93 0.0247894,
94 QStringLiteral("BEF"),
95 i18nc("currency name", "Belgian Franc"),
96 i18nc("BEF Belgian Franc - unit synonyms for matching user input", "franc;francs") + QStringLiteral(";BEF;")
97 + QLocale::territoryToString(QLocale::Belgium) + QLatin1Char(';') + i18nc("currency name", "Belgian Franc"),
98 symbolString,
99 ki18nc("amount in units (real)", "%1 Belgian francs"),
100 ki18ncp("amount in units (integer)", "%1 Belgian franc", "%1 Belgian francs")));
101
102 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
103 Nlg,
104 0.45378,
105 QStringLiteral("NLG"),
106 i18nc("currency name", "Netherlands Guilder"),
107 i18nc("NLG Netherlands Guilder - unit synonyms for matching user input", "guilder;guilders") + QStringLiteral(";NLG;")
108 + QLocale::territoryToString(QLocale::Netherlands) + QLatin1Char(';') + i18nc("currency name", "Netherlands Guilder"),
109 symbolString,
110 ki18nc("amount in units (real)", "%1 guilders"),
111 ki18ncp("amount in units (integer)", "%1 guilder", "%1 guilders")));
112
113 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
114 Fim,
115 0.168188,
116 QStringLiteral("FIM"),
117 i18nc("currency name", "Finnish Markka"),
118 i18nc("FIM Finnish Markka - unit synonyms for matching user input", "markka;markkas;markkaa") + QStringLiteral(";FIM;")
119 + QLocale::territoryToString(QLocale::Finland) + QLatin1Char(';') + i18nc("currency name", "Finnish Markka"),
120 symbolString,
121 ki18nc("amount in units (real)", "%1 markkas"),
122 ki18ncp("amount in units (integer)", "%1 markka", "%1 markkas"))); // Alternative = markkaa
123
124 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
125 Frf,
126 0.152449,
127 QStringLiteral("FRF"),
128 i18nc("currency name", "French Franc"),
129 i18nc("FRF French Franc - unit synonyms for matching user input", "franc;francs") + QStringLiteral(";FRF;")
130 + QLocale::territoryToString(QLocale::France) + QLatin1Char(';') + i18nc("currency name", "French Franc"),
131 symbolString,
132 ki18nc("amount in units (real)", "%1 French francs"),
133 ki18ncp("amount in units (integer)", "%1 French franc", "%1 French francs")));
134
135 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
136 Dem,
137 0.511292,
138 QStringLiteral("DEM"),
139 i18nc("currency name", "German Mark"),
140 i18nc("DEM German Mark - unit synonyms for matching user input", "mark;marks") + QStringLiteral(";DEM;")
141 + QLocale::territoryToString(QLocale::Germany) + QLatin1Char(';') + i18nc("currency name", "German Mark"),
142 symbolString,
143 ki18nc("amount in units (real)", "%1 marks"),
144 ki18ncp("amount in units (integer)", "%1 mark", "%1 marks")));
145
146 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
147 Iep,
148 1.26974,
149 QStringLiteral("IEP"),
150 i18nc("currency name", "Irish Pound"),
151 i18nc("IEP Irish Pound - unit synonyms for matching user input", "Irish pound;Irish pounds") + QStringLiteral(";IEP;")
152 + QLocale::territoryToString(QLocale::Ireland) + QLatin1Char(';') + i18nc("currency name", "Irish Pound"),
153 symbolString,
154 ki18nc("amount in units (real)", "%1 Irish pounds"),
155 ki18ncp("amount in units (integer)", "%1 Irish pound", "%1 Irish pounds")));
156
157 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
158 Itl,
159 0.000516457,
160 QStringLiteral("ITL"),
161 i18nc("currency name", "Italian Lira"),
162 i18nc("ITL Italian Lira - unit synonyms for matching user input", "lira;liras") + QStringLiteral(";ITL;")
163 + QLocale::territoryToString(QLocale::Italy) + QLatin1Char(';') + i18nc("currency name", "Italian Lira"),
164 symbolString,
165 ki18nc("amount in units (real)", "%1 Italian lira"),
166 ki18ncp("amount in units (integer)", "%1 Italian lira", "%1 Italian lira")));
167
168 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
169 Luf,
170 0.0247894,
171 QStringLiteral("LUF"),
172 i18nc("currency name", "Luxembourgish Franc"),
173 i18nc("LUF Luxembourgish Franc - unit synonyms for matching user input", "franc;francs") + QStringLiteral(";LUF;")
174 + QLocale::territoryToString(QLocale::Luxembourg) + QLatin1Char(';') + i18nc("currency name", "Luxembourgish Franc"),
175 symbolString,
176 ki18nc("amount in units (real)", "%1 Luxembourgish francs"),
177 ki18ncp("amount in units (integer)", "%1 Luxembourgish franc", "%1 Luxembourgish francs")));
178
179 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
180 Pte,
181 0.00498798,
182 QStringLiteral("PTE"),
183 i18nc("currency name", "Portuguese Escudo"),
184 i18nc("PTE Portuguese Escudo - unit synonyms for matching user input", "escudo;escudos") + QStringLiteral(";PTE;")
185 + QLocale::territoryToString(QLocale::Portugal) + QLatin1Char(';') + i18nc("currency name", "Portuguese Escudo"),
186 symbolString,
187 ki18nc("amount in units (real)", "%1 escudos"),
188 ki18ncp("amount in units (integer)", "%1 escudo", "%1 escudos")));
189
190 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
191 Esp,
192 0.00601012,
193 QStringLiteral("ESP"),
194 i18nc("currency name", "Spanish Peseta"),
195 i18nc("ESP Spanish Peseta - unit synonyms for matching user input", "peseta;pesetas") + QStringLiteral(";ESP;")
196 + QLocale::territoryToString(QLocale::Spain) + QLatin1Char(';') + i18nc("currency name", "Spanish Peseta"),
197 symbolString,
198 ki18nc("amount in units (real)", "%1 pesetas"),
199 ki18ncp("amount in units (integer)", "%1 peseta", "%1 pesetas")));
200
201 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
202 Grd,
203 0.0029347,
204 QStringLiteral("GRD"),
205 i18nc("currency name", "Greek Drachma"),
206 i18nc("GRD Greek Drachma - unit synonyms for matching user input", "drachma;drachmas") + QStringLiteral(";GRD;")
207 + QLocale::territoryToString(QLocale::Greece) + QLatin1Char(';') + i18nc("currency name", "Greek Drachma"),
208 symbolString,
209 ki18nc("amount in units (real)", "%1 drachmas"),
210 ki18ncp("amount in units (integer)", "%1 drachma", "%1 drachmas")));
211
212 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
213 Sit,
214 0.00417293,
215 QStringLiteral("SIT"),
216 i18nc("currency name", "Slovenian Tolar"),
217 i18nc("SIT Slovenian Tolar - unit synonyms for matching user input", "tolar;tolars;tolarjev") + QStringLiteral(";SIT;")
218 + QLocale::territoryToString(QLocale::Slovenia) + QLatin1Char(';') + i18nc("currency name", "Slovenian Tolar"),
219 symbolString,
220 ki18nc("amount in units (real)", "%1 tolars"),
221 ki18ncp("amount in units (integer)", "%1 tolar", "%1 tolars"))); // Alt: tolarjev/tolarja/tolarji
222
223 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
224 Cyp,
225 1.7086,
226 QStringLiteral("CYP"),
227 i18nc("currency name", "Cypriot Pound"),
228 i18nc("CYP Cypriot Pound - unit synonyms for matching user input", "Cypriot pound;Cypriot pounds") + QStringLiteral(";CYP;")
229 + QLocale::territoryToString(QLocale::Cyprus) + QLatin1Char(';') + i18nc("currency name", "Cypriot Pound"),
230 symbolString,
231 ki18nc("amount in units (real)", "%1 Cypriot pounds"),
232 ki18ncp("amount in units (integer)", "%1 Cypriot pound", "%1 Cypriot pounds")));
233
234 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
235 Mtl,
236 2.32937,
237 QStringLiteral("MTL"),
238 i18nc("currency name", "Maltese Lira"),
239 i18nc("MTL Maltese Lira - unit synonyms for matching user input", "Maltese lira") + QStringLiteral(";MTL;")
240 + QLocale::territoryToString(QLocale::Malta) + QLatin1Char(';') + i18nc("currency name", "Maltese Lira"),
241 symbolString,
242 ki18nc("amount in units (real)", "%1 Maltese lira"),
243 ki18ncp("amount in units (integer)", "%1 Maltese lira", "%1 Maltese lira")));
244
245 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
246 Skk,
247 0.0331939,
248 QStringLiteral("SKK"),
249 i18nc("currency name", "Slovak Koruna"),
250 i18nc("SKK Slovak Koruna - unit synonyms for matching user input", "koruna;korunas;koruny;korun") + QStringLiteral(";SKK;")
251 + QLocale::territoryToString(QLocale::Slovakia) + QLatin1Char(';') + i18nc("currency name", "Slovak Koruna"),
252 symbolString,
253 ki18nc("amount in units (real)", "%1 Slovak korunas"),
254 ki18ncp("amount in units (integer)", "%1 Slovak koruna", "%1 Slovak korunas"))); // Alt: koruny, korun
255
256 // From ECB
257 d->addCommonUnit(UnitPrivate::makeUnit(CurrencyCategory,
258 Usd,
259 qSNaN(),
260 QStringLiteral("USD"),
261 i18nc("currency name", "United States Dollar"),
262 i18nc("USD United States Dollar - unit synonyms for matching user input", "dollar;dollars") + QStringLiteral(";USD;$;")
263 + QLocale::territoryToString(QLocale::UnitedStates) + QLatin1Char(';') + i18nc("currency name", "United States Dollar"),
264 symbolString,
265 ki18nc("amount in units (real)", "%1 United States dollars"),
266 ki18ncp("amount in units (integer)", "%1 United States dollar", "%1 United States dollars")));
267
268 d->addCommonUnit(UnitPrivate::makeUnit(CurrencyCategory,
269 Jpy,
270 qSNaN(),
271 QStringLiteral("JPY"),
272 i18nc("currency name", "Japanese Yen"),
273 i18nc("JPY Japanese Yen - unit synonyms for matching user input", "yen") + QStringLiteral(";JPY;") + QStringLiteral("¥")
274 + QLatin1Char(';') + QLocale::territoryToString(QLocale::Japan) + QLatin1Char(';') + i18nc("currency name", "Japanese Yen"),
275 symbolString,
276 ki18nc("amount in units (real)", "%1 yen"),
277 ki18ncp("amount in units (integer)", "%1 yen", "%1 yen")));
278
279 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
280 Bgn,
281 qSNaN(),
282 QStringLiteral("BGN"),
283 i18nc("currency name", "Bulgarian Lev"),
284 i18nc("BGN Bulgarian Lev - unit synonyms for matching user input", "lev;leva") + QStringLiteral(";BGN;")
285 + QLocale::territoryToString(QLocale::Bulgaria) + QLatin1Char(';') + i18nc("currency name", "Bulgarian Lev"),
286 symbolString,
287 ki18nc("amount in units (real)", "%1 leva"),
288 ki18ncp("amount in units (integer)", "%1 lev", "%1 leva")));
289
290 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
291 Czk,
292 qSNaN(),
293 QStringLiteral("CZK"),
294 i18nc("currency name", "Czech Koruna"),
295 i18nc("CZK Czech Koruna - unit synonyms for matching user input", "koruna;korunas") + QStringLiteral(";CZK;")
296 + QLocale::territoryToString(QLocale::CzechRepublic) + QLatin1Char(';') + i18nc("currency name", "Czech Koruna"),
297 symbolString,
298 ki18nc("amount in units (real)", "%1 Czech korunas"),
299 // Alt: koruny, korun
300 ki18ncp("amount in units (integer)", "%1 Czech koruna", "%1 Czech korunas")));
301
302 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
303 Dkk,
304 qSNaN(),
305 QStringLiteral("DKK"),
306 i18nc("currency name", "Danish Krone"),
307 i18nc("DKK Danish Krone - unit synonyms for matching user input", "Danish krone;Danish kroner") + QStringLiteral(";DKK;")
308 + QLocale::territoryToString(QLocale::Denmark) + QLatin1Char(';') + i18nc("currency name", "Danish Krone"),
309 symbolString,
310 ki18nc("amount in units (real)", "%1 Danish kroner"),
311 ki18ncp("amount in units (integer)", "%1 Danish krone", "%1 Danish kroner")));
312
313 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
314 Eek,
315 qSNaN(),
316 QStringLiteral("EEK"),
317 i18nc("currency name", "Estonian Kroon"),
318 i18nc("EEK Estonian Kroon - unit synonyms for matching user input", "kroon;kroons;krooni") + QStringLiteral(";EEK;")
319 + QLocale::territoryToString(QLocale::Estonia) + QLatin1Char(';') + i18nc("currency name", "Estonian Kroon"),
320 symbolString,
321 ki18nc("amount in units (real)", "%1 kroons"),
322 ki18ncp("amount in units (integer)", "%1 kroon", "%1 kroons"))); // Alt: krooni
323
324 d->addCommonUnit(UnitPrivate::makeUnit(CurrencyCategory,
325 Gbp,
326 qSNaN(),
327 QStringLiteral("GBP"),
328 i18nc("currency name", "British Pound"),
329 i18nc("GBP British Pound - unit synonyms for matching user input", "pound;pounds;pound sterling;pounds sterling")
330 + QStringLiteral(";GBP;") + QStringLiteral("£") + QLatin1Char(';') + QLocale::territoryToString(QLocale::UnitedKingdom)
331 + QLatin1Char(';') + i18nc("currency name", "British Pound"),
332 symbolString,
333 ki18nc("amount in units (real)", "%1 pounds sterling"),
334 ki18ncp("amount in units (integer)", "%1 pound sterling", "%1 pounds sterling")));
335
336 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
337 Huf,
338 qSNaN(),
339 QStringLiteral("HUF"),
340 i18nc("currency name", "Hungarian Forint"),
341 i18nc("HUF hungarian Forint - unit synonyms for matching user input", "forint") + QStringLiteral(";HUF;")
342 + QLocale::territoryToString(QLocale::Hungary) + QLatin1Char(';') + i18nc("currency name", "Hungarian Forint"),
343 symbolString,
344 ki18nc("amount in units (real)", "%1 forint"),
345 ki18ncp("amount in units (integer)", "%1 forint", "%1 forint")));
346
347 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
348 Ils,
349 qSNaN(),
350 QStringLiteral("ILS"),
351 i18nc("currency name", "Israeli New Shekel"),
352 i18nc("ILS Israeli New Shekel - unit synonyms for matching user input", "shekel;shekels;sheqel;sheqels;sheqalim")
353 + QStringLiteral(";ILS;") + QLocale::territoryToString(QLocale::Israel) + QLatin1Char(';')
354 + i18nc("currency name", "Israeli New Shekel"),
355 symbolString,
356 ki18nc("amount in units (real)", "%1 shekels"),
357 ki18ncp("amount in units (integer)", "%1 shekel", "%1 shekels")));
358
359 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
360 Ltl,
361 qSNaN(),
362 QStringLiteral("LTL"),
363 i18nc("currency name", "Lithuanian Litas"),
364 i18nc("LTL Lithuanian Litas - unit synonyms for matching user input", "litas;litai;litu") + QStringLiteral(";LTL;")
365 + QLocale::territoryToString(QLocale::Lithuania) + QLatin1Char(';') + i18nc("currency name", "Lithuanian Litas"),
366 symbolString,
367 ki18nc("amount in units (real)", "%1 litas"),
368 ki18ncp("amount in units (integer)", "%1 litas", "%1 litai"))); // Alt: litu
369
370 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
371 Lvl,
372 qSNaN(),
373 QStringLiteral("LVL"),
374 i18nc("currency name", "Latvian Lats"),
375 i18nc("LVL Latvian Lats - unit synonyms for matching user input", "lats;lati") + QStringLiteral(";LVL;")
376 + QLocale::territoryToString(QLocale::Latvia) + QLatin1Char(';') + i18nc("currency name", "Latvian Lats"),
377 symbolString,
378 ki18nc("amount in units (real)", "%1 lati"),
379 ki18ncp("amount in units (integer)", "%1 lats", "%1 lati")));
380
381 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
382 Pln,
383 qSNaN(),
384 QStringLiteral("PLN"),
385 i18nc("currency name", "Polish Zloty"),
386 i18nc("PLN Polish Zloty - unit synonyms for matching user input", "zloty;zlotys;zloties") + QStringLiteral(";PLN;")
387 + QLocale::territoryToString(QLocale::Poland) + QLatin1Char(';') + i18nc("currency name", "Polish Zloty"),
388 symbolString,
389 ki18nc("amount in units (real)", "%1 zlotys"),
390 ki18ncp("amount in units (integer)", "%1 zloty", "%1 zlotys"))); // Alt: zloty, zlote, zlotych
391
392 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
393 Ron,
394 qSNaN(),
395 QStringLiteral("RON"),
396 i18nc("currency name", "Romanian Leu"),
397 i18nc("RON Romanian Leu - unit synonyms for matching user input", "leu;lei") + QStringLiteral(";RON;")
398 + QLocale::territoryToString(QLocale::Romania) + QLatin1Char(';') + i18nc("currency name", "Romanian Leu"),
399 symbolString,
400 ki18nc("amount in units (real)", "%1 lei"),
401 ki18ncp("amount in units (integer)", "%1 leu", "%1 lei")));
402
403 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
404 Sek,
405 qSNaN(),
406 QStringLiteral("SEK"),
407 i18nc("currency name", "Swedish Krona"),
408 i18nc("SEK Swedish Krona - unit synonyms for matching user input", "krona;kronor") + QStringLiteral(";SEK;")
409 + QLocale::territoryToString(QLocale::Sweden) + QLatin1Char(';') + i18nc("currency name", "Swedish Krona"),
410 symbolString,
411 ki18nc("amount in units (real)", "%1 kronor"),
412 ki18ncp("amount in units (integer)", "%1 krona", "%1 kronor")));
413
414 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
415 Chf,
416 qSNaN(),
417 QStringLiteral("CHF"),
418 i18nc("currency name", "Swiss Franc"),
419 i18nc("CHF Swiss Franc - unit synonyms for matching user input", "franc;francs") + QStringLiteral(";CHF;")
420 + QLocale::territoryToString(QLocale::Switzerland) + QLatin1Char(';') + i18nc("currency name", "Swiss Franc"),
421 symbolString,
422 ki18nc("amount in units (real)", "%1 Swiss francs"),
423 ki18ncp("amount in units (integer)", "%1 Swiss franc", "%1 Swiss francs")));
424
425 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
426 Nok,
427 qSNaN(),
428 QStringLiteral("NOK"),
429 i18nc("currency name", "Norwegian Krone"),
430 i18nc("Norwegian Krone - unit synonyms for matching user input", "Norwegian krone;Norwegian kroner") + QStringLiteral(";NOK;")
431 + QLocale::territoryToString(QLocale::Norway) + QLatin1Char(';') + i18nc("currency name", "Norwegian Krone"),
432 symbolString,
433 ki18nc("amount in units (real)", "%1 Norwegian kroner"),
434 ki18ncp("amount in units (integer)", "%1 Norwegian krone", "%1 Norwegian kroner")));
435
436 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
437 Hrk,
438 1.0/7.53450,
439 QStringLiteral("HRK"),
440 i18nc("currency name", "Croatian Kuna"),
441 i18nc("HRK Croatian Kuna - unit synonyms for matching user input", "kuna;kune") + QStringLiteral(";HRK;")
442 + QLocale::territoryToString(QLocale::Croatia) + QLatin1Char(';') + i18nc("currency name", "Croatian Kuna"),
443 symbolString,
444 ki18nc("amount in units (real)", "%1 kune"),
445 ki18ncp("amount in units (integer)", "%1 kuna", "%1 kune")));
446
447 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
448 Rub,
449 qSNaN(),
450 QStringLiteral("RUB"),
451 i18nc("currency name", "Russian Ruble"),
452 i18nc("RUB Russian Ruble - unit synonyms for matching user input", "ruble;rubles;rouble;roubles") + QStringLiteral(";RUB;")
453 + QLocale::territoryToString(QLocale::Russia) + QLatin1Char(';') + i18nc("currency name", "Russian Ruble"),
454 symbolString,
455 ki18nc("amount in units (real)", "%1 rubles"),
456 ki18ncp("amount in units (integer)", "%1 ruble", "%1 rubles"))); // Alt: rouble/roubles
457
458 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
459 Try,
460 qSNaN(),
461 QStringLiteral("TRY"),
462 i18nc("currency name", "Turkish Lira"),
463 i18nc("TRY Turkish Lira - unit synonyms for matching user input", "lira") + QStringLiteral(";TRY;")
464 + QLocale::territoryToString(QLocale::Turkey) + QLatin1Char(';') + i18nc("currency name", "Turkish Lira"),
465 symbolString,
466 ki18nc("amount in units (real)", "%1 Turkish lira"),
467 ki18ncp("amount in units (integer)", "%1 Turkish lira", "%1 Turkish lira")));
468
469 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
470 Aud,
471 qSNaN(),
472 QStringLiteral("AUD"),
473 i18nc("currency name", "Australian Dollar"),
474 i18nc("AUD Australian Dollar - unit synonyms for matching user input", "Australian dollar;Australian dollars") + QStringLiteral(";AUD;")
475 + QLocale::territoryToString(QLocale::Australia) + QLatin1Char(';') + i18nc("currency name", "Australian Dollar"),
476 symbolString,
477 ki18nc("amount in units (real)", "%1 Australian dollars"),
478 ki18ncp("amount in units (integer)", "%1 Australian dollar", "%1 Australian dollars")));
479
480 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
481 Brl,
482 qSNaN(),
483 QStringLiteral("BRL"),
484 i18nc("currency name", "Brazilian Real"),
485 i18nc("BRL Brazilian Real - unit synonyms for matching user input", "real;reais") + QStringLiteral(";BRL;")
486 + QLocale::territoryToString(QLocale::Brazil) + QLatin1Char(';') + i18nc("currency name", "Brazilian Real"),
487 symbolString,
488 ki18nc("amount in units (real)", "%1 reais"),
489 ki18ncp("amount in units (integer)", "%1 real", "%1 reais")));
490
491 d->addCommonUnit(UnitPrivate::makeUnit(CurrencyCategory,
492 Cad,
493 qSNaN(),
494 QStringLiteral("CAD"),
495 i18nc("currency name", "Canadian Dollar"),
496 i18nc("Canadian Dollar - unit synonyms for matching user input", "Canadian dollar;Canadian dollars") + QStringLiteral(";CAD;")
497 + QLocale::territoryToString(QLocale::Canada) + QLatin1Char(';') + i18nc("currency name", "Canadian Dollar"),
498 symbolString,
499 ki18nc("amount in units (real)", "%1 Canadian dollars"),
500 ki18ncp("amount in units (integer)", "%1 Canadian dollar", "%1 Canadian dollars")));
501
502 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
503 Cny,
504 qSNaN(),
505 QStringLiteral("CNY"),
506 i18nc("currency name", "Chinese Yuan"),
507 i18nc("Chinese Yuan - unit synonyms for matching user input", "yuan") + QStringLiteral(";CNY;")
508 + QLocale::territoryToString(QLocale::China) + QLatin1Char(';') + i18nc("currency name", "Chinese Yuan"),
509 symbolString,
510 ki18nc("amount in units (real)", "%1 yuan"),
511 ki18ncp("amount in units (integer)", "%1 yuan", "%1 yuan")));
512
513 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
514 Hkd,
515 qSNaN(),
516 QStringLiteral("HKD"),
517 i18nc("currency name", "Hong Kong Dollar"),
518 i18nc("Hong Kong Dollar - unit synonyms for matching user input", "Hong Kong dollar;Hong Kong dollars") + QStringLiteral(";HKD;")
519 + QLocale::territoryToString(QLocale::HongKong) + QLatin1Char(';') + i18nc("currency name", "Hong Kong Dollar"),
520 symbolString,
521 ki18nc("amount in units (real)", "%1 Hong Kong dollars"),
522 ki18ncp("amount in units (integer)", "%1 Hong Kong dollar", "%1 Hong Kong dollars")));
523
524 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
525 Idr,
526 qSNaN(),
527 QStringLiteral("IDR"),
528 i18nc("currency name", "Indonesian Rupiah"),
529 i18nc("IDR Indonesian Rupiah - unit synonyms for matching user input", "rupiah;rupiahs") + QStringLiteral(";IDR;")
530 + QLocale::territoryToString(QLocale::Indonesia) + QLatin1Char(';') + i18nc("currency name", "Indonesian Rupiah"),
531 symbolString,
532 ki18nc("amount in units (real)", "%1 rupiahs"),
533 ki18ncp("amount in units (integer)", "%1 rupiah", "%1 rupiahs"))); // Alt: rupiah
534
535 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
536 Inr,
537 qSNaN(),
538 QStringLiteral("INR"),
539 i18nc("currency name", "Indian Rupee"),
540 i18nc("INR Indian Rupee - unit synonyms for matching user input", "rupee;rupees") + QStringLiteral(";INR;")
541 + QLocale::territoryToString(QLocale::India) + QLatin1Char(';') + i18nc("currency name", "Indian Rupee"),
542 symbolString,
543 ki18nc("amount in units (real)", "%1 rupees"),
544 ki18ncp("amount in units (integer)", "%1 rupee", "%1 rupees"))); // Alt: rupee
545
546 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
547 Krw,
548 qSNaN(),
549 QStringLiteral("KRW"),
550 i18nc("currency name", "Korean Won"),
551 i18nc("KRW Korean Won - unit synonyms for matching user input", "won") + QStringLiteral(";KRW;")
552 + QLocale::territoryToString(QLocale::SouthKorea) + QLatin1Char(';') + i18nc("currency name", "Korean Won"),
553 symbolString,
554 ki18nc("amount in units (real)", "%1 won"),
555 ki18ncp("amount in units (integer)", "%1 won", "%1 won")));
556
557 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
558 Mxn,
559 qSNaN(),
560 QStringLiteral("MXN"),
561 i18nc("currency name", "Mexican Peso"),
562 i18nc("MXN Mexican Peso - unit synonyms for matching user input", "Mexican peso;Mexican pesos") + QStringLiteral(";MXN;")
563 + QLocale::territoryToString(QLocale::Mexico) + QLatin1Char(';') + i18nc("currency name", "Mexican Peso"),
564 symbolString,
565 ki18nc("amount in units (real)", "%1 Mexican pesos"),
566 ki18ncp("amount in units (integer)", "%1 Mexican peso", "%1 Mexican pesos")));
567
568 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
569 Myr,
570 qSNaN(),
571 QStringLiteral("MYR"),
572 i18nc("currency name", "Malaysian Ringgit"),
573 i18nc("MYR Malaysian Ringgit - unit synonyms for matching user input", "ringgit;ringgits") + QStringLiteral(";MYR;")
574 + QLocale::territoryToString(QLocale::Malaysia) + QLatin1Char(';') + i18nc("currency name", "Malaysian Ringgit"),
575 symbolString,
576 ki18nc("amount in units (real)", "%1 ringgit"),
577 ki18ncp("amount in units (integer)", "%1 ringgit", "%1 ringgit"))); // Alt: ringgits
578
579 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
580 Nzd,
581 qSNaN(),
582 QStringLiteral("NZD"),
583 i18nc("currency name", "New Zealand Dollar"),
584 i18nc("NZD New Zealand Dollar - unit synonyms for matching user input", "New Zealand dollar;New Zealand dollars")
585 + QStringLiteral(";NZD;") + QLocale::territoryToString(QLocale::NewZealand) + QLatin1Char(';')
586 + i18nc("currency name", "New Zealand Dollar"),
587 symbolString,
588 ki18nc("amount in units (real)", "%1 New Zealand dollars"),
589 ki18ncp("amount in units (integer)", "%1 New Zealand dollar", "%1 New Zealand dollars")));
590
591 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
592 Php,
593 qSNaN(),
594 QStringLiteral("PHP"),
595 i18nc("currency name", "Philippine Peso"),
596 i18nc("PHP Philippine Peso - unit synonyms for matching user input", "Philippine peso;Philippine pesos") + QStringLiteral(";PHP;")
597 + QLocale::territoryToString(QLocale::Philippines) + QLatin1Char(';') + i18nc("currency name", "Philippine Peso"),
598 symbolString,
599 ki18nc("amount in units (real)", "%1 Philippine pesos"),
600 ki18ncp("amount in units (integer)", "%1 Philippine peso", "%1 Philippine pesos")));
601
602 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
603 Sgd,
604 qSNaN(),
605 QStringLiteral("SGD"),
606 i18nc("currency name", "Singapore Dollar"),
607 i18nc("SGD Singapore Dollar - unit synonyms for matching user input", "Singapore dollar;Singapore dollars") + QStringLiteral(";SGD;")
608 + QLocale::territoryToString(QLocale::Singapore) + QLatin1Char(';') + i18nc("currency name", "Singapore Dollar"),
609 symbolString,
610 ki18nc("amount in units (real)", "%1 Singapore dollars"),
611 ki18ncp("amount in units (integer)", "%1 Singapore dollar", "%1 Singapore dollars")));
612
613 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
614 Thb,
615 qSNaN(),
616 QStringLiteral("THB"),
617 i18nc("currency name", "Thai Baht"),
618 i18nc("THB Thai Baht - unit synonyms for matching user input", "baht") + QStringLiteral(";THB;")
619 + QLocale::territoryToString(QLocale::Thailand) + QLatin1Char(';') + i18nc("currency name", "Thai Baht"),
620 symbolString,
621 ki18nc("amount in units (real)", "%1 baht"),
622 ki18ncp("amount in units (integer)", "%1 baht", "%1 baht")));
623
624 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
625 Zar,
626 qSNaN(),
627 QStringLiteral("ZAR"),
628 i18nc("currency name", "South African Rand"),
629 i18nc("South African Rand - unit synonyms for matching user input", "rand") + QStringLiteral(";ZAR;")
630 + QLocale::territoryToString(QLocale::SouthAfrica) + QLatin1Char(';') + i18nc("currency name", "South African Rand"),
631 symbolString,
632 ki18nc("amount in units (real)", "%1 rand"),
633 ki18ncp("amount in units (integer)", "%1 rand", "%1 rand")));
634 d->addUnit(UnitPrivate::makeUnit(CurrencyCategory,
635 Isk,
636 qSNaN(),
637 QStringLiteral("ISK"),
638 i18nc("currency name", "Icelandic Krona"),
639 i18nc("Icelandic Krona - unit synonyms for matching user input", "Icelandic krona;Icelandic crown") + QStringLiteral(";ISK;")
640 + QLocale::territoryToString(QLocale::Iceland) + QLatin1Char(';') + i18nc("currency name", "Icelandic Krona"),
641 symbolString,
642 ki18nc("amount in units (real)", "%1 Icelandic kronar"),
643 ki18ncp("amount in units (integer)", "%1 Icelandic krona", "%1 Icelandic kronar")));
644
645 return c;
646}
647
648static bool isConnected()
649{
650 // don't download currencies in autotests
651 if (qEnvironmentVariableIsSet("KF5UNITCONVERT_NO_DOWNLOAD")) {
652 return false;
653 }
654 bool ret = false;
655 const auto listInterface = QNetworkInterface::allInterfaces();
656 for (const QNetworkInterface &net : listInterface) {
657 if (net.flags().testFlag(QNetworkInterface::IsUp) && !net.flags().testFlag(QNetworkInterface::IsLoopBack)) {
658 ret = true;
659 break;
660 }
661 }
662 return ret;
663}
664
665QDateTime Currency::lastConversionTableUpdate()
666{
667 QFileInfo info(cacheLocation());
668 if (!info.exists()) {
669 qCDebug(LOG_KUNITCONVERSION) << "No cache file available:" << cacheLocation();
670 return QDateTime();
671 } else {
672 return info.lastModified();
673 }
674}
675
676UpdateJob* CurrencyCategoryPrivate::syncConversionTable(std::chrono::seconds updateSkipPeriod)
677{
678 QFileInfo info(cacheLocation());
679 if (info.exists() && info.lastModified().secsTo(QDateTime::currentDateTime()) <= updateSkipPeriod.count()) {
680 return nullptr; // already present and up to date
681 }
682 if (!isConnected()) {
683 qCInfo(LOG_KUNITCONVERSION) << "currency conversion table update has no network connection, abort update";
684 return nullptr;
685 }
686 if (m_currentReply) {
687 return makeUpdateJob(m_currentReply);
688 }
689
690 qCDebug(LOG_KUNITCONVERSION) << "currency conversion table sync started";
691 m_currentReply = nam()->get(QNetworkRequest(QUrl(QString::fromLatin1(URL))));
692 QObject::connect(m_currentReply, &QNetworkReply::finished, [this] {
693 auto reply = m_currentReply;
694 m_currentReply = nullptr;
695 reply->deleteLater();
696 if (reply->error()) {
697 qCWarning(LOG_KUNITCONVERSION) << "currency conversion table network error" << reply->errorString();
698 return;
699 }
700 const auto cachePath = cacheLocation();
701 QFileInfo info(cachePath);
702 const QString cacheDir = info.absolutePath();
703 if (!QFileInfo::exists(cacheDir)) {
704 QDir().mkpath(cacheDir);
705 }
706
707 QSaveFile cacheFile(cachePath);
708 if (!cacheFile.open(QFile::WriteOnly)) {
709 qCCritical(LOG_KUNITCONVERSION) << cacheFile.errorString();
710 return;
711 }
712 cacheFile.write(reply->readAll());
713 if (!cacheFile.commit()) {
714 qCCritical(LOG_KUNITCONVERSION) << cacheFile.errorString();
715 return;
716 }
717 qCInfo(LOG_KUNITCONVERSION) << "currency conversion table data obtained via network";
718 m_initialized = readConversionTable(cachePath);
719 });
720
721 return makeUpdateJob(m_currentReply);
722}
723
724bool CurrencyCategoryPrivate::readConversionTable(const QString &cachePath)
725{
726 QFile file(cachePath);
727 if (!file.open(QIODevice::ReadOnly)) {
728 return false;
729 }
730 QXmlStreamReader xml(&file);
731 while (!xml.atEnd()) {
732 xml.readNext();
733
734 if (xml.isStartElement() && xml.name() == QLatin1String("Cube")) {
735 const auto attributes = xml.attributes();
736 if (attributes.hasAttribute(QLatin1String("currency"))) {
737 Unit unit = m_unitMap.value(attributes.value(QLatin1String("currency")).toString());
738 if (unit.isValid()) {
739 const auto multiplier = attributes.value(QLatin1String("rate")).toDouble();
740 if (!qFuzzyIsNull(multiplier)) {
741 unit.setUnitMultiplier(1.0 / multiplier);
742 qCDebug(LOG_KUNITCONVERSION()) << "currency updated:" << unit.description() << multiplier;
743 }
744 }
745 }
746 }
747 }
748
749 if (xml.hasError()) {
750 qCCritical(LOG_KUNITCONVERSION) << "currency conversion fetch could not parse obtained XML, update aborted";
751 return false;
752 }
753 return true;
754}
755
756Value CurrencyCategoryPrivate::convert(const Value &value, const Unit &to)
757{
758 if (!m_initialized) {
759 m_initialized = readConversionTable(cacheLocation());
760 }
761
762 Value v = UnitCategoryPrivate::convert(value, to);
763 return v;
764}
765
766} // KUnitConversion namespace
QString i18nc(const char *context, const char *text, const TYPE &arg...)
KLocalizedString KI18N_EXPORT ki18ncp(const char *context, const char *singular, const char *plural)
KLocalizedString KI18N_EXPORT ki18nc(const char *context, const char *text)
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
QString name(StandardAction id)
QDateTime currentDateTime()
bool mkpath(const QString &dirPath) const const
bool exists() const const
QString territoryToString(Territory territory)
QList< QNetworkInterface > allInterfaces()
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
QString writableLocation(StandardLocation type)
QString fromLatin1(QByteArrayView str)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:15:24 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.