From 3fa38c11efae920c6af47142df825b47fd583f29 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Mon, 9 Sep 2019 13:18:24 +0200 Subject: [PATCH] Current state --- README.md | 50 +- app.pro | 22 +- data/currencies.csv | 304 ++-- data/currencies.json | 1514 ++++++++--------- data/currencies_de_DE.csv | 170 -- data/currencies_de_DE.json | 509 ------ data/currencies_de_DE.txt | 169 -- data/currencies_en_GB.json | 509 ------ data/currencies_fi_FI.csv | 170 -- data/currencies_fi_FI.json | 509 ------ data/currencies_fi_FI.txt | 169 -- data/translation_procedure.txt | 15 +- harbour-currencyconverter.pro | 3 + qml/components/Cache.qml | 97 ++ qml/components/Currencies.qml | 164 ++ qml/components/Currency.qml | 55 + qml/components/CurrencyCombo.qml | 128 +- qml/components/CurrencyList.qml | 138 ++ qml/components/CurrencyModel.qml | 265 ++- .../{CurrencyItem.qml => CurrencyPair.qml} | 27 +- qml/components/Env.qml | 60 + qml/components/ExchangeProvider.qml | 192 ++- qml/components/ExchangeRatesAPIProvider.qml | 112 +- qml/components/JSONListModel.qml | 56 - qml/components/Network.qml | 48 + qml/components/Requester.qml | 11 +- qml/components/Settings.qml | 48 +- qml/components/Storage.qml | 82 +- qml/components/qmldir | 4 + qml/components/requester.mjs | 24 +- qml/components/utils.js | 42 + qml/cover/CoverPage.qml | 26 +- qml/harbour-currencyconverter.qml | 314 ++-- qml/pages/AboutPage.qml | 2 +- qml/pages/FrontPage.qml | 274 ++- qml/pages/SearchPage.qml | 141 -- qml/pages/SettingsDialog.qml | 43 +- src/harbour-currencyconverter.cpp | 8 +- 38 files changed, 2493 insertions(+), 3981 deletions(-) delete mode 100644 data/currencies_de_DE.csv delete mode 100644 data/currencies_de_DE.json delete mode 100644 data/currencies_de_DE.txt delete mode 100644 data/currencies_en_GB.json delete mode 100644 data/currencies_fi_FI.csv delete mode 100644 data/currencies_fi_FI.json delete mode 100644 data/currencies_fi_FI.txt create mode 100644 qml/components/Cache.qml create mode 100644 qml/components/Currencies.qml create mode 100644 qml/components/Currency.qml create mode 100644 qml/components/CurrencyList.qml rename qml/components/{CurrencyItem.qml => CurrencyPair.qml} (77%) create mode 100644 qml/components/Env.qml delete mode 100644 qml/components/JSONListModel.qml create mode 100644 qml/components/Network.qml create mode 100644 qml/components/qmldir delete mode 100644 qml/pages/SearchPage.qml diff --git a/README.md b/README.md index c823bb3..5161d45 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,43 @@ ![Icon](https://raw.githubusercontent.com/tanghus/currency-converter-qml/master/harbour-currencyconverter.png) Currency Converter for SailfishOS ================================= -| branch | status | -| ----------- | ------ | -| master | [![Build Status](https://travis-ci.org/tanghus/currency-converter-qml.png?branch=master)](https://travis-ci.org/tanghus/currency-converter-qml) | +Convert currencies using data configurable currency rates providers. -[![flattr this](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=tanghus&url=https%3A%2F%2Fgithub.com%2Ftanghus%2Fcurrency-converter-qml) +Currency Converter per default uses {https://ExchangeRatesAPI.io](https://exchangeratesapi.io/) +that offers daily exchange rates for a limited set of currencies (currently 33) published by +the [European Central Bank](https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html). -Convert currencies using data from Yahoo! Finance. +With Currency Converter you can select different Exchange Rates Providers to get +faster updates, more options, and a wider set of currencies. +Most commercial providers also offers a free version, but with some caveats, as for +example not being able to request a base currency, with the result that each time you +request one new currency pair, all of them will be downloaded. +So unless you *really* need to, I strongly recommend sticking with the default. -**Current** features: - - Select to and/or from the dropdown list and the converted amount will be updated. - - Change the amount to be converted and the result will be updated. - - Selected currencies and amount is saved between sessions. - - Refresh selected convertion when no activity for a user defined period of time, or by request. - - Selected exchange rates is shown real-time on the home screen cover. - - Swap currently selected currencies. +For the average traveller or businessperson the default selection should be more than enough. -**Planned** features (in time for first release): - - Well, pretty much done, I think. +If you - like me - have a combination of lousy math skills and bad short-time memory, +the quick switch of currencies comes in handy ;) + +Currency Converter keeps an internal list of registered, legal currencies, which is +used together with a list of the currencies offered by the chosen provider. The latter +is refreshed when the app is loaded, except if there is no network connection, or if +you have explicitly chosen to work offline. +For this Currency Converter uses an effective caching mechanism. Based on the update interval +of the current provider, and timestamps on each currency pair (e.g. EUR/USD) it only fetches +online rates when needed - or, again, when explicitly told to. + +You can chose to delete the cache for one pair or the entire cache. + +**Be aware**, that if you delete the entire cache, the list of available currencies will +have to be downloaded once again. It's not a very big payload, though, but if you're offline +it could be problematic. + +**Also be aware**, that the list of available currencies is dependant on which 'From Currency' +you had selected selected when the app is loaded. +That means, that if you change the 'From Currency' right after you go offline, there is +no guarantee that a list of the available currencies can be generated from the cache. +To remedy this, change to the 'From Currency' you need to be cached, close the app, and +launch it again. I'll put an option in to load them on demand if I get that request. -**Planned** features (or maybe just brain barfs): - - Select (short) list of currencies to monitor and notify on change (within a range). diff --git a/app.pro b/app.pro index ee830c3..add0242 100644 --- a/app.pro +++ b/app.pro @@ -16,20 +16,24 @@ OTHER_FILES += Changelog README.md icons flags DISTFILES += qml/cover/CoverPage.qml \ TODO.md \ qml/$${TARGET}.qml \ + qml/components/Currencies.qml \ + qml/components/Currency.qml \ + qml/components/CurrencyCombo.qml \ + qml/components/CurrencyModel.qml \ + qml/components/CurrencyPair.qml \ + qml/components/qmldir \ + qml/components/Env.qml \ + qml/components/Network.qml \ qml/components/ExchangeRatesAPIProvider.qml \ - qml/pages/FrontPage.qml \ - qml/pages/SettingsDialog.qml \ - qml/pages/SearchPage.qml \ - qml/pages/AboutPage.qml \ + qml/components/ExchangeProvider.qml \ qml/components/Requester.qml \ qml/components/Settings.qml \ - qml/components/JSONListModel.qml \ - qml/components/CurrencyModel.qml \ - qml/components/CurrencyItem.qml \ - qml/components/CurrencyCombo.qml \ + qml/components/CurrencyList.qml \ qml/components/Notification.qml \ qml/components/Storage.qml \ - qml/components/ExchangeProvider.qml \ + qml/pages/FrontPage.qml \ + qml/pages/SettingsDialog.qml \ + qml/pages/AboutPage.qml \ rpm/$${TARGET}.changes.in \ rpm/$${TARGET}.changes.run.in \ rpm/$${TARGET}.spec \ diff --git a/data/currencies.csv b/data/currencies.csv index 57167b5..7ac4212 100644 --- a/data/currencies.csv +++ b/data/currencies.csv @@ -1,152 +1,152 @@ -"code","num","symbol","name" -"AED","د.إ","784","UAE Dirham" -"AFN","Af","971","Afghan Afghani" -"ALL","L","008","Albanian Lek" -"AMD","Դ","051","Armenian Dram" -"AOA","Kz","973","Kwanza" -"ARS","$","032","Argentine Peso" -"AUD","$","036","Australian Dollar" -"AWG","ƒ","533","Aruban Guilder/Florin" -"AZN","ман","944","Azerbaijanian Manat" -"BAM","КМ","977","Konvertibilna Marka" -"BBD","$","052","Barbados Dollar" -"BDT","৳","050","Bangladeshi Taka" -"BGN","лв","975","Bulgarian Lev" -"BHD","ب.د","048","Bahraini Dinar" -"BIF","₣","108","Burundi Franc" -"BMD","$","060","Bermudian Dollar" -"BND","$","096","Brunei Dollar" -"BOB","Bs.","068","Bolivian Boliviano" -"BRL","R$","986","Brazilian Real" -"BSD","$","044","Bahamian Dollar" -"BTN","","064","Bhutan Ngultrum" -"BWP","P","072","Botswanan Pula" -"BYR","Br","974","Belarussian Ruble" -"BZD","$","084","Belize Dollar" -"CAD","$","124","Canadian Dollar" -"CDF","₣","976","Congolese Franc" -"CHF","₣","756","Swiss Franc" -"CLP","$","152","Chilean Peso" -"CNY","¥","156","Chinese Yuan" -"COP","$","170","Colombian Peso" -"CRC","₡","188","Costa Rican Colon" -"CUP","$","192","Cuban Peso" -"CVE","$","132","Cape Verde Escudo" -"CZK","Kč","203","Czech Koruna" -"DJF","₣","262","Djibouti Franc" -"DKK","kr","208","Danish Krone" -"DOP","$","214","Dominican Peso" -"DZD","د.ج","012","Algerian Dinar" -"EGP","£","818","Egyptian Pound" -"ERN","Nfk","232","Eritrean Nakfa" -"ETB"," 230","Ethiopian Birr" -"EUR","€","978","Euro" -"FJD","$","242","Fiji Dollar" -"FKP","£","238","Falkland Islands Pound" -"GBP","£","826","Pound Sterling" -"GEL","ლ","981","Georgian Lari" -"GHS","₵","936","Ghanaian Cedi" -"GIP","£","292","Gibraltar Pound" -"GMD","D","270","Gambian Dalasi" -"GNF","₣","324","Guinea Franc" -"GTQ","Q","320","Guatemalan Quetzal" -"GYD","$","328","Guyana Dollar" -"HKD","$","344","Hong Kong Dollar" -"HNL","L","340","Honduran Lempira" -"HRK","Kn","191","Croatian Kuna" -"HTG","G","332","Haitian Gourde" -"HUF","Ft","348","Hungarian Forint" -"IDR","Rp","360","Indonesian Rupiah" -"ILS","₪","376","New Israeli Shekel" -"INR","₹","356","Indian Rupee" -"IQD","ع.د","368","Iraqi Dinar" -"IRR","﷼","364","Iranian Rial" -"ISK","Kr","352","Iceland Krona" -"JMD","$","388","Jamaican Dollar" -"JOD","د.ا","400","Jordanian Dinar" -"JPY","¥","392","Japanese Yen" -"KES","Sh","404","Kenyan Shilling" -"KGS"," 417","Kyrgyzstani Som" -"KHR","៛","116","Cambodian Riel" -"KPW","₩","408","North Korean Won" -"KRW","₩","410","South Korean Won" -"KWD","د.ك","414","Kuwaiti Dinar" -"KYD","$","136","Cayman Islands Dollar" -"KZT","〒","398","Kazakhstani Tenge" -"LAK","₭","418","Laotian Kip" -"LBP","ل.ل","422","Lebanese Pound" -"LKR","Rs","144","Sri Lanka Rupee" -"LRD","$","430","Liberian Dollar" -"LSL","L","426","Lesotho Loti" -"LYD","ل.د","434","Libyan Dinar" -"MAD","د.م.","504","Moroccan Dirham" -"MDL","L","498","Moldavian Leu" -"MGA","","969","Malagasy Ariary" -"MKD","ден","807","Macedonian Denar" -"MMK","K","104","Myanmar Kyat" -"MNT","₮","496","Mongolian Tugrik" -"MOP","P","446","Macanese Pataca" -"MRO","UM","478","Mauritanian Ouguiya" -"MUR","₨","480","Mauritius Rupee" -"MVR","ރ.","462","Maldivan Rufiyaa" -"MWK","MK","454","Malawian Kwacha" -"MXN","$","484","Mexican Peso" -"MYR","RM","458","Malaysian Ringgit" -"MZN","MTn","943","Mozambican Metical" -"NAD","$","516","Namibia Dollar" -"NGN","₦","566","Nigerian Naira" -"NIO","C$","558","Nicaraguan Cordoba Oro" -"NOK","kr","578","Norwegian Krone" -"NPR","₨","524","Nepalese Rupee" -"NZD","$","554","New Zealand Dollar" -"OMR","ر.ع.","512","Rial Omani" -"PAB","B/.","590","Panaman Balboa" -"PEN","S/.","604","Peruvian Nuevo Sol" -"PGK","K","598","Papua New Guinean Kina" -"PHP","₱","608","Philippine Peso" -"PKR","₨","586","Pakistan Rupee" -"PLN","zł","985","Polish Zloty" -"PYG","₲","600","Paraguayan Guarani" -"QAR","ر.ق","634","Qatari Rial" -"RON","L","946","Romania Leu" -"RSD","din","941","Serbian Dinar" -"RUB","р.","643","Russian Ruble" -"RWF","₣","646","Rwanda Franc" -"SAR","ر.س","682","Saudi Riyal" -"SBD","$","090","Solomon Islands Dollar" -"SCR","₨","690","Seychelles Rupee" -"SDG","£","938","Sudanese Pound" -"SEK","kr","752","Swedish Krona" -"SGD","$","702","Singapore Dollar" -"SHP","£","654","Saint Helena Pound" -"SLL","Le","694","Sierra Leonean Leone" -"SOS","Sh","706","Somali Shilling" -"SRD","$","968","Suriname Dollar" -"STD","Db","678","Sao Tome and Principe Dobra" -"SYP","ل.س","760","Syrian Pound" -"SZL","L","748","Swazi Lilangeni" -"THB","฿","764","Thai Baht" -"TJS","ЅМ","972","Tajikistani Somoni" -"TMT","m","934","Turkmenistan Manat" -"TND","د.ت","788","Tunisian Dinar" -"TOP","T$","776","Tongan Pa’anga" -"TRY","₤","949","Turkish Lira" -"TTD","$","780","Trinidad and Tobago Dollar" -"TWD","$","901","Taiwan Dollar" -"TZS","Sh","834","Tanzanian Shilling" -"UAH","₴","980","Ukrainian Hryvnia" -"UGX","Sh","800","Uganda Shilling" -"USD","$","840","US Dollar" -"UYU","$","858","Uruguayan Peso" -"UZS","","860","Uzbekistan Sum" -"VEF","Bs F","937","Venezuelan Bolivar Fuerte" -"VND","₫","704","Vietnamese Dong" -"VUV","Vt","548","Vanuatu Vatu" -"WST","T","882","Samoan Tala" -"XAF","₣","950","CFA Franc BCEAO" -"XCD","$","951","East Caribbean Dollar" -"XPF","₣","953","CFP Franc" -"YER","﷼","886","Yemeni Rial" -"ZAR","R","710","Rand" -"ZMW","ZK","967","Zambian Kwacha" -"ZWL","$","932","Zimbabwe Dollar" +"code","symbol","num","name" +"AED","\u062F\u002E\u0625","784","UAE Dirham" +"AFN","\u0041\u0066","971","Afghan Afghani" +"ALL","\u004c","008","Albanian Lek" +"AMD","\u058F","051","Armenian Dram" +"AOA","\u004b\u007a","973","Kwanza" +"ARS","\u0024","032","Argentine Peso" +"AUD","\u0024","036","Australian Dollar" +"AWG","\u0192","533","Aruban Guilder/Florin" +"AZN","\u20BC","944","Azerbaijanian Manat" +"BAM","\u041a\u041c","977","Konvertibilna Marka" +"BBD","\u0024","052","Barbados Dollar" +"BDT","\u09F3","050","Bangladeshi Taka" +"BGN","\u043b\u0432","975","Bulgarian Lev" +"BHD","\u0628\u002e\u062f","048","Bahraini Dinar" +"BIF","\u20A3","108","Burundi Franc" +"BMD","\u0024","060","Bermudian Dollar" +"BND","\u0024","096","Brunei Dollar" +"BOB","\u0042\u0073\u002e","068","Bolivian Boliviano" +"BRL","R\u0024","986","Brazilian Real" +"BSD","\u0024","044","Bahamian Dollar" +"BTN","\u004e\u0075\u002e","064","Bhutan Ngultrum" +"BWP","\u0050","072","Botswanan Pula" +"BYR","\u0042\u0072","974","Belarussian Ruble" +"BZD","\u0024","084","Belize Dollar" +"CAD","\u0024","124","Canadian Dollar" +"CDF","\u20A3","976","Congolese Franc" +"CHF","\u20A3","756","Swiss Franc" +"CLP","\u0024","152","Chilean Peso" +"CNY","\u00a5","156","Chinese Yuan" +"COP","\u0024","170","Colombian Peso" +"CRC","\u20A1","188","Costa Rican Colon" +"CUP","\u0024","192","Cuban Peso" +"CVE","\u0024","132","Cape Verde Escudo" +"CZK","\u004b\u010d","203","Czech Koruna" +"DJF","\u20A3","262","Djibouti Franc" +"DKK","\u006b\u0072","208","Danish Krone" +"DOP","\u0024","214","Dominican Peso" +"DZD","\u062f\u002e\u062c","012","Algerian Dinar" +"EGP","\u00a3","818","Egyptian Pound" +"ERN","\u004e\u0066\u006b","232","Eritrean Nakfa" +"ETB","\u0042\u0072","230","Ethiopian Birr" +"EUR","\u20AC","978","Euro" +"FJD","\u0024","242","Fiji Dollar" +"FKP","\u00a3","238","Falkland Islands Pound" +"GBP","\u00a3","826","Pound Sterling" +"GEL","\u10da","981","Georgian Lari" +"GHS","\u20b5","936","Ghanaian Cedi" +"GIP","\u00a3","292","Gibraltar Pound" +"GMD","\u0044","270","Gambian Dalasi" +"GNF","\u20A3","324","Guinea Franc" +"GTQ","\u0051","320","Guatemalan Quetzal" +"GYD","\u0024","328","Guyana Dollar" +"HKD","\u0024","344","Hong Kong Dollar" +"HNL","\u004c","340","Honduran Lempira" +"HRK","\u004b\u006e","191","Croatian Kuna" +"HTG","\u004b\u006e","332","Haitian Gourde" +"HUF","\u0046\u0074","348","Hungarian Forint" +"IDR","\u0052\u0070","360","Indonesian Rupiah" +"ILS","\u20aa","376","New Israeli Shekel" +"INR","\u20b9","356","Indian Rupee" +"IQD","\u0639\u002e\u062f","368"Iraqi Dinar" +"IRR","\ufdfc","364","Iranian Rial" +"ISK","\u004b\u0072","352","Iceland Krona" +"JMD","\u0024","388","Jamaican Dollar" +"JOD","\u062f\u002e\u0627","400","Jordanian Dinar" +"JPY","\u00a5","392","Japanese Yen" +"KES","\u0053\u0068","404","Kenyan Shilling" +"KGS","\u0441\u043e\u043c","417","Kyrgyzstani Som" +"KHR","\u17db","116","Cambodian Riel" +"KPW","\u20a9","408","North Korean Won" +"KRW","\u20a9","410","South Korean Won" +"KWD","\u062f\u002e\u0643","414","Kuwaiti Dinar" +"KYD","\u0024","136","Cayman Islands Dollar" +"KZT","\u3012","398","Kazakhstani Tenge" +"LAK","\u20ad","418","Laotian Kip" +"LBP","\u0644\u002e\u0644","422","Lebanese Pound" +"LKR","\u0052\u0073","144","Sri Lanka Rupee" +"LRD","\u0024","430","Liberian Dollar" +"LSL","\u004c","426","Lesotho Loti" +"LYD","\u0644\u002e\u062f","434","Libyan Dinar" +"MAD","\u062f\u002e\u0645.","504","Moroccan Dirham" +"MDL","\u004c","498","Moldavian Leu" +"MGA","\u0041\u0072","969","Malagasy Ariary" +"MKD","\u0434\u0435\u043d","807","Macedonian Denar" +"MMK","\u004b","104","Myanmar Kyat" +"MNT","\u20ae","496","Mongolian Tugrik" +"MOP","\u0050","446","Macanese Pataca" +"MRO","\u0055\u004d","478","Mauritanian Ouguiya" +"MUR","\u20a8","480","Mauritius Rupee" +"MVR","\u0783\u002e","462","Maldivan Rufiyaa" +"MWK","\u004d\u004b","454","Malawian Kwacha" +"MXN","\u0024","484","Mexican Peso" +"MYR","\u0052\u004d","458","Malaysian Ringgit" +"MZN","\u004d\u0054\u006e","943","Mozambican Metical" +"NAD","\u0024","516","Namibia Dollar" +"NGN","\u20a6","566","Nigerian Naira" +"NIO","C\u0024","558","Nicaraguan Cordoba Oro" +"NOK","\u006b\u0072","578","Norwegian Krone" +"NPR","\u20a8","524","Nepalese Rupee" +"NZD","\u0024","554","New Zealand Dollar" +"OMR","\u0631\u002e\u0639\u002e","512","Rial Omani" +"PAB","\u0042\u002f\u002e","590","Panaman Balboa" +"PEN","\u0053\u002f\u002e","604","Peruvian Nuevo Sol" +"PGK","\u004b","598","Papua New Guinean Kina" +"PHP","\u20b1","608","Philippine Peso" +"PKR","\u20a8","586","Pakistan Rupee" +"PLN","\u007a\u0142","985","Polish Zloty" +"PYG","\u20b2","600","Paraguayan Guarani" +"QAR","\u0631\u002e\u0642","634","Qatari Rial" +"RON","\u004c","946","Romania Leu" +"RSD","\u0064\u0069\u006e","941","Serbian Dinar" +"RUB","\u20bd","643","Russian Ruble" +"RWF","\u20A3","646","Rwanda Franc" +"SAR","\u0631\u002e\u0633","682","Saudi Riyal" +"SBD","\u0024","090","Solomon Islands Dollar" +"SCR","\u20a8","690","Seychelles Rupee" +"SDG","\u00a3","938","Sudanese Pound" +"SEK","\u006b\u0072","752","Swedish Krona" +"SGD","\u0024","702","Singapore Dollar" +"SHP","\u00a3","654","Saint Helena Pound" +"SLL","\u004c\u0065","694","Sierra Leonean Leone" +"SOS","\u0053\u0068","706","Somali Shilling" +"SRD","\u0024","968","Suriname Dollar" +"STD","\u0044\u0062","678","Sao Tome and Principe Dobra" +"SYP","\u0644\u002e\u0633","760","Syrian Pound" +"SZL","\u004c","748","Swazi Lilangeni" +"THB","\u0e3f","764","Thai Baht" +"TJS","\u0405\u041c","972","Tajikistani Somoni" +"TMT","\u006d","934","Turkmenistan Manat" +"TND","\u062f\u002e\u062a","788","Tunisian Dinar" +"TOP","T\u0024","776","Tongan Pa’anga" +"TRY","\u20a4","949","Turkish Lira" +"TTD","\u0024","780","Trinidad and Tobago Dollar" +"TWD","\u0024","901","Taiwan Dollar" +"TZS","\u0053\u0068","834","Tanzanian Shilling" +"UAH","\u20b4","980","Ukrainian Hryvnia" +"UGX","\u0053\u0068","800","Uganda Shilling" +"USD","\u0024","840","US Dollar" +"UYU","\u0024","858","Uruguayan Peso" +"UZS","\u0441\u045e\u043c","860","Uzbekistan Sum" +"VEF","\u0042\u0073 \u0046","937","Venezuelan Bolivar Fuerte" +"VND","\u20ab","704","Vietnamese Dong" +"VUV","\u0056\u0074","548","Vanuatu Vatu" +"WST","\u0054","882","Samoan Tala" +"XAF","\u20A3","950","CFA Franc BCEAO" +"XCD","\u0024","951","East Caribbean Dollar" +"XPF","\u20A3","953","CFP Franc" +"YER","\ufdfc","886","Yemeni Rial" +"ZAR","\u0052","710","Rand" +"ZMW","\u005a\u004b","967","Zambian Kwacha" +"ZWL","\u0024","932","Zimbabwe Dollar" diff --git a/data/currencies.json b/data/currencies.json index 4b1f1a9..b698f99 100644 --- a/data/currencies.json +++ b/data/currencies.json @@ -1,757 +1,757 @@ -{ - "AED": { - "num": "د.إ", - "symbol": "784", - "name": "UAE Dirham" - }, - "AFN": { - "num": "Af", - "symbol": "971", - "name": "Afghan Afghani" - }, - "ALL": { - "num": "L", - "symbol": "008", - "name": "Albanian Lek" - }, - "AMD": { - "num": "Դ", - "symbol": "051", - "name": "Armenian Dram" - }, - "AOA": { - "num": "Kz", - "symbol": "973", - "name": "Kwanza" - }, - "ARS": { - "num": "$", - "symbol": "032", - "name": "Argentine Peso" - }, - "AUD": { - "num": "$", - "symbol": "036", - "name": "Australian Dollar" - }, - "AWG": { - "num": "ƒ", - "symbol": "533", - "name": "Aruban Guilder/Florin" - }, - "AZN": { - "num": "ман", - "symbol": "944", - "name": "Azerbaijanian Manat" - }, - "BAM": { - "num": "КМ", - "symbol": "977", - "name": "Konvertibilna Marka" - }, - "BBD": { - "num": "$", - "symbol": "052", - "name": "Barbados Dollar" - }, - "BDT": { - "num": "৳", - "symbol": "050", - "name": "Bangladeshi Taka" - }, - "BGN": { - "num": "лв", - "symbol": "975", - "name": "Bulgarian Lev" - }, - "BHD": { - "num": "ب.د", - "symbol": "048", - "name": "Bahraini Dinar" - }, - "BIF": { - "num": "₣", - "symbol": "108", - "name": "Burundi Franc" - }, - "BMD": { - "num": "$", - "symbol": "060", - "name": "Bermudian Dollar" - }, - "BND": { - "num": "$", - "symbol": "096", - "name": "Brunei Dollar" - }, - "BOB": { - "num": "Bs.", - "symbol": "068", - "name": "Bolivian Boliviano" - }, - "BRL": { - "num": "R$", - "symbol": "986", - "name": "Brazilian Real" - }, - "BSD": { - "num": "$", - "symbol": "044", - "name": "Bahamian Dollar" - }, - "BTN": { - "num": "", - "symbol": "064", - "name": "Bhutan Ngultrum" - }, - "BWP": { - "num": "P", - "symbol": "072", - "name": "Botswanan Pula" - }, - "BYR": { - "num": "Br", - "symbol": "974", - "name": "Belarussian Ruble" - }, - "BZD": { - "num": "$", - "symbol": "084", - "name": "Belize Dollar" - }, - "CAD": { - "num": "$", - "symbol": "124", - "name": "Canadian Dollar" - }, - "CDF": { - "num": "₣", - "symbol": "976", - "name": "Congolese Franc" - }, - "CHF": { - "num": "₣", - "symbol": "756", - "name": "Swiss Franc" - }, - "CLP": { - "num": "$", - "symbol": "152", - "name": "Chilean Peso" - }, - "CNY": { - "num": "¥", - "symbol": "156", - "name": "Chinese Yuan" - }, - "COP": { - "num": "$", - "symbol": "170", - "name": "Colombian Peso" - }, - "CRC": { - "num": "₡", - "symbol": "188", - "name": "Costa Rican Colon" - }, - "CUP": { - "num": "$", - "symbol": "192", - "name": "Cuban Peso" - }, - "CVE": { - "num": "$", - "symbol": "132", - "name": "Cape Verde Escudo" - }, - "CZK": { - "num": "Kč", - "symbol": "203", - "name": "Czech Koruna" - }, - "DJF": { - "num": "₣", - "symbol": "262", - "name": "Djibouti Franc" - }, - "DKK": { - "num": "kr", - "symbol": "208", - "name": "Danish Krone" - }, - "DOP": { - "num": "$", - "symbol": "214", - "name": "Dominican Peso" - }, - "DZD": { - "num": "د.ج", - "symbol": "012", - "name": "Algerian Dinar" - }, - "EGP": { - "num": "£", - "symbol": "818", - "name": "Egyptian Pound" - }, - "ERN": { - "num": "Nfk", - "symbol": "232", - "name": "Eritrean Nakfa" - }, - "ETB": { - "num": "\t230", - "symbol": "Ethiopian Birr", - "name": "" - }, - "EUR": { - "num": "€", - "symbol": "978", - "name": "Euro" - }, - "FJD": { - "num": "$", - "symbol": "242", - "name": "Fiji Dollar" - }, - "FKP": { - "num": "£", - "symbol": "238", - "name": "Falkland Islands Pound" - }, - "GBP": { - "num": "£", - "symbol": "826", - "name": "Pound Sterling" - }, - "GEL": { - "num": "ლ", - "symbol": "981", - "name": "Georgian Lari" - }, - "GHS": { - "num": "₵", - "symbol": "936", - "name": "Ghanaian Cedi" - }, - "GIP": { - "num": "£", - "symbol": "292", - "name": "Gibraltar Pound" - }, - "GMD": { - "num": "D", - "symbol": "270", - "name": "Gambian Dalasi" - }, - "GNF": { - "num": "₣", - "symbol": "324", - "name": "Guinea Franc" - }, - "GTQ": { - "num": "Q", - "symbol": "320", - "name": "Guatemalan Quetzal" - }, - "GYD": { - "num": "$", - "symbol": "328", - "name": "Guyana Dollar" - }, - "HKD": { - "num": "$", - "symbol": "344", - "name": "Hong Kong Dollar" - }, - "HNL": { - "num": "L", - "symbol": "340", - "name": "Honduran Lempira" - }, - "HRK": { - "num": "Kn", - "symbol": "191", - "name": "Croatian Kuna" - }, - "HTG": { - "num": "G", - "symbol": "332", - "name": "Haitian Gourde" - }, - "HUF": { - "num": "Ft", - "symbol": "348", - "name": "Hungarian Forint" - }, - "IDR": { - "num": "Rp", - "symbol": "360", - "name": "Indonesian Rupiah" - }, - "ILS": { - "num": "₪", - "symbol": "376", - "name": "New Israeli Shekel" - }, - "INR": { - "num": "₹", - "symbol": "356", - "name": "Indian Rupee" - }, - "IQD": { - "num": "ع.د", - "symbol": "368", - "name": "Iraqi Dinar" - }, - "IRR": { - "num": "﷼", - "symbol": "364", - "name": "Iranian Rial" - }, - "ISK": { - "num": "Kr", - "symbol": "352", - "name": "Iceland Krona" - }, - "JMD": { - "num": "$", - "symbol": "388", - "name": "Jamaican Dollar" - }, - "JOD": { - "num": "د.ا", - "symbol": "400", - "name": "Jordanian Dinar" - }, - "JPY": { - "num": "¥", - "symbol": "392", - "name": "Japanese Yen" - }, - "KES": { - "num": "Sh", - "symbol": "404", - "name": "Kenyan Shilling" - }, - "KGS": { - "num": "\t417", - "symbol": "Kyrgyzstani Som", - "name": "" - }, - "KHR": { - "num": "៛", - "symbol": "116", - "name": "Cambodian Riel" - }, - "KPW": { - "num": "₩", - "symbol": "408", - "name": "North Korean Won" - }, - "KRW": { - "num": "₩", - "symbol": "410", - "name": "South Korean Won" - }, - "KWD": { - "num": "د.ك", - "symbol": "414", - "name": "Kuwaiti Dinar" - }, - "KYD": { - "num": "$", - "symbol": "136", - "name": "Cayman Islands Dollar" - }, - "KZT": { - "num": "〒", - "symbol": "398", - "name": "Kazakhstani Tenge" - }, - "LAK": { - "num": "₭", - "symbol": "418", - "name": "Laotian Kip" - }, - "LBP": { - "num": "ل.ل", - "symbol": "422", - "name": "Lebanese Pound" - }, - "LKR": { - "num": "Rs", - "symbol": "144", - "name": "Sri Lanka Rupee" - }, - "LRD": { - "num": "$", - "symbol": "430", - "name": "Liberian Dollar" - }, - "LSL": { - "num": "L", - "symbol": "426", - "name": "Lesotho Loti" - }, - "LYD": { - "num": "ل.د", - "symbol": "434", - "name": "Libyan Dinar" - }, - "MAD": { - "num": "د.م.", - "symbol": "504", - "name": "Moroccan Dirham" - }, - "MDL": { - "num": "L", - "symbol": "498", - "name": "Moldavian Leu" - }, - "MGA": { - "num": "", - "symbol": "969", - "name": "Malagasy Ariary" - }, - "MKD": { - "num": "ден", - "symbol": "807", - "name": "Macedonian Denar" - }, - "MMK": { - "num": "K", - "symbol": "104", - "name": "Myanmar Kyat" - }, - "MNT": { - "num": "₮", - "symbol": "496", - "name": "Mongolian Tugrik" - }, - "MOP": { - "num": "P", - "symbol": "446", - "name": "Macanese Pataca" - }, - "MRO": { - "num": "UM", - "symbol": "478", - "name": "Mauritanian Ouguiya" - }, - "MUR": { - "num": "₨", - "symbol": "480", - "name": "Mauritius Rupee" - }, - "MVR": { - "num": "ރ.", - "symbol": "462", - "name": "Maldivan Rufiyaa" - }, - "MWK": { - "num": "MK", - "symbol": "454", - "name": "Malawian Kwacha" - }, - "MXN": { - "num": "$", - "symbol": "484", - "name": "Mexican Peso" - }, - "MYR": { - "num": "RM", - "symbol": "458", - "name": "Malaysian Ringgit" - }, - "MZN": { - "num": "MTn", - "symbol": "943", - "name": "Mozambican Metical" - }, - "NAD": { - "num": "$", - "symbol": "516", - "name": "Namibia Dollar" - }, - "NGN": { - "num": "₦", - "symbol": "566", - "name": "Nigerian Naira" - }, - "NIO": { - "num": "C$", - "symbol": "558", - "name": "Nicaraguan Cordoba Oro" - }, - "NOK": { - "num": "kr", - "symbol": "578", - "name": "Norwegian Krone" - }, - "NPR": { - "num": "₨", - "symbol": "524", - "name": "Nepalese Rupee" - }, - "NZD": { - "num": "$", - "symbol": "554", - "name": "New Zealand Dollar" - }, - "OMR": { - "num": "ر.ع.", - "symbol": "512", - "name": "Rial Omani" - }, - "PAB": { - "num": "B/.", - "symbol": "590", - "name": "Panaman Balboa" - }, - "PEN": { - "num": "S/.", - "symbol": "604", - "name": "Peruvian Nuevo Sol" - }, - "PGK": { - "num": "K", - "symbol": "598", - "name": "Papua New Guinean Kina" - }, - "PHP": { - "num": "₱", - "symbol": "608", - "name": "Philippine Peso" - }, - "PKR": { - "num": "₨", - "symbol": "586", - "name": "Pakistan Rupee" - }, - "PLN": { - "num": "zł", - "symbol": "985", - "name": "Polish Zloty" - }, - "PYG": { - "num": "₲", - "symbol": "600", - "name": "Paraguayan Guarani" - }, - "QAR": { - "num": "ر.ق", - "symbol": "634", - "name": "Qatari Rial" - }, - "RON": { - "num": "L", - "symbol": "946", - "name": "Romania Leu" - }, - "RSD": { - "num": "din", - "symbol": "941", - "name": "Serbian Dinar" - }, - "RUB": { - "num": "р.", - "symbol": "643", - "name": "Russian Ruble" - }, - "RWF": { - "num": "₣", - "symbol": "646", - "name": "Rwanda Franc" - }, - "SAR": { - "num": "ر.س", - "symbol": "682", - "name": "Saudi Riyal" - }, - "SBD": { - "num": "$", - "symbol": "090", - "name": "Solomon Islands Dollar" - }, - "SCR": { - "num": "₨", - "symbol": "690", - "name": "Seychelles Rupee" - }, - "SDG": { - "num": "£", - "symbol": "938", - "name": "Sudanese Pound" - }, - "SEK": { - "num": "kr", - "symbol": "752", - "name": "Swedish Krona" - }, - "SGD": { - "num": "$", - "symbol": "702", - "name": "Singapore Dollar" - }, - "SHP": { - "num": "£", - "symbol": "654", - "name": "Saint Helena Pound" - }, - "SLL": { - "num": "Le", - "symbol": "694", - "name": "Sierra Leonean Leone" - }, - "SOS": { - "num": "Sh", - "symbol": "706", - "name": "Somali Shilling" - }, - "SRD": { - "num": "$", - "symbol": "968", - "name": "Suriname Dollar" - }, - "STD": { - "num": "Db", - "symbol": "678", - "name": "Sao Tome and Principe Dobra" - }, - "SYP": { - "num": "ل.س", - "symbol": "760", - "name": "Syrian Pound" - }, - "SZL": { - "num": "L", - "symbol": "748", - "name": "Swazi Lilangeni" - }, - "THB": { - "num": "฿", - "symbol": "764", - "name": "Thai Baht" - }, - "TJS": { - "num": "ЅМ", - "symbol": "972", - "name": "Tajikistani Somoni" - }, - "TMT": { - "num": "m", - "symbol": "934", - "name": "Turkmenistan Manat" - }, - "TND": { - "num": "د.ت", - "symbol": "788", - "name": "Tunisian Dinar" - }, - "TOP": { - "num": "T$", - "symbol": "776", - "name": "Tongan Pa’anga" - }, - "TRY": { - "num": "₤", - "symbol": "949", - "name": "Turkish Lira" - }, - "TTD": { - "num": "$", - "symbol": "780", - "name": "Trinidad and Tobago Dollar" - }, - "TWD": { - "num": "$", - "symbol": "901", - "name": "Taiwan Dollar" - }, - "TZS": { - "num": "Sh", - "symbol": "834", - "name": "Tanzanian Shilling" - }, - "UAH": { - "num": "₴", - "symbol": "980", - "name": "Ukrainian Hryvnia" - }, - "UGX": { - "num": "Sh", - "symbol": "800", - "name": "Uganda Shilling" - }, - "USD": { - "num": "$", - "symbol": "840", - "name": "US Dollar" - }, - "UYU": { - "num": "$", - "symbol": "858", - "name": "Uruguayan Peso" - }, - "UZS": { - "num": "", - "symbol": "860", - "name": "Uzbekistan Sum" - }, - "VEF": { - "num": "Bs F", - "symbol": "937", - "name": "Venezuelan Bolivar Fuerte" - }, - "VND": { - "num": "₫", - "symbol": "704", - "name": "Vietnamese Dong" - }, - "VUV": { - "num": "Vt", - "symbol": "548", - "name": "Vanuatu Vatu" - }, - "WST": { - "num": "T", - "symbol": "882", - "name": "Samoan Tala" - }, - "XAF": { - "num": "₣", - "symbol": "950", - "name": "CFA Franc BCEAO" - }, - "XCD": { - "num": "$", - "symbol": "951", - "name": "East Caribbean Dollar" - }, - "XPF": { - "num": "₣", - "symbol": "953", - "name": "CFP Franc" - }, - "YER": { - "num": "﷼", - "symbol": "886", - "name": "Yemeni Rial" - }, - "ZAR": { - "num": "R", - "symbol": "710", - "name": "Rand" - }, - "ZMW": { - "num": "ZK", - "symbol": "967", - "name": "Zambian Kwacha" - }, - "ZWL": { - "num": "$", - "symbol": "932", - "name": "Zimbabwe Dollar" - } -} +{ + "AED": { + "symbol": "\u062F\u002E\u0625", + "num": 784, + "name": "UAE Dirham" + }, + "AFN": { + "symbol": "\u0041\u0066", + "num": 971, + "name": "Afghan Afghani" + }, + "ALL": { + "symbol": "\u004c", + "num": 8, + "name": "Albanian Lek" + }, + "AMD": { + "symbol": "\u058F", + "num": 51, + "name": "Armenian Dram" + }, + "AOA": { + "symbol": "\u004b\u007a", + "num": 973, + "name": "Kwanza" + }, + "ARS": { + "symbol": "\u0024", + "num": 32, + "name": "Argentine Peso" + }, + "AUD": { + "symbol": "\u0024", + "num": 36, + "name": "Australian Dollar" + }, + "AWG": { + "symbol": "\u0192", + "num": 533, + "name": "Aruban Guilder/Florin" + }, + "AZN": { + "symbol": "\u20BC", + "num": 944, + "name": "Azerbaijanian Manat" + }, + "BAM": { + "symbol": "\u041a\u041c", + "num": 977, + "name": "Konvertibilna Marka" + }, + "BBD": { + "symbol": "\u0024", + "num": 52, + "name": "Barbados Dollar" + }, + "BDT": { + "symbol": "\u09F3", + "num": 50, + "name": "Bangladeshi Taka" + }, + "BGN": { + "symbol": "\u043b\u0432", + "num": 975, + "name": "Bulgarian Lev" + }, + "BHD": { + "symbol": "\u0628\u002e\u062f", + "num": 48, + "name": "Bahraini Dinar" + }, + "BIF": { + "symbol": "\u20A3", + "num": 108, + "name": "Burundi Franc" + }, + "BMD": { + "symbol": "\u0024", + "num": 60, + "name": "Bermudian Dollar" + }, + "BND": { + "symbol": "\u0024", + "num": 96, + "name": "Brunei Dollar" + }, + "BOB": { + "symbol": "\u0042\u0073\u002e", + "num": 68, + "name": "Bolivian Boliviano" + }, + "BRL": { + "symbol": "R\u0024", + "num": 986, + "name": "Brazilian Real" + }, + "BSD": { + "symbol": "\u0024", + "num": 44, + "name": "Bahamian Dollar" + }, + "BTN": { + "symbol": "\u004e\u0075\u002e", + "num": 64, + "name": "Bhutan Ngultrum" + }, + "BWP": { + "symbol": "\u0050", + "num": 72, + "name": "Botswanan Pula" + }, + "BYR": { + "symbol": "\u0042\u0072", + "num": 974, + "name": "Belarussian Ruble" + }, + "BZD": { + "symbol": "\u0024", + "num": 84, + "name": "Belize Dollar" + }, + "CAD": { + "symbol": "\u0024", + "num": 124, + "name": "Canadian Dollar" + }, + "CDF": { + "symbol": "\u20A3", + "num": 976, + "name": "Congolese Franc" + }, + "CHF": { + "symbol": "\u20A3", + "num": 756, + "name": "Swiss Franc" + }, + "CLP": { + "symbol": "\u0024", + "num": 152, + "name": "Chilean Peso" + }, + "CNY": { + "symbol": "\u00a5", + "num": 156, + "name": "Chinese Yuan" + }, + "COP": { + "symbol": "\u0024", + "num": 170, + "name": "Colombian Peso" + }, + "CRC": { + "symbol": "\u20A1", + "num": 188, + "name": "Costa Rican Colon" + }, + "CUP": { + "symbol": "\u0024", + "num": 192, + "name": "Cuban Peso" + }, + "CVE": { + "symbol": "\u0024", + "num": 132, + "name": "Cape Verde Escudo" + }, + "CZK": { + "symbol": "\u004b\u010d", + "num": 203, + "name": "Czech Koruna" + }, + "DJF": { + "symbol": "\u20A3", + "num": 262, + "name": "Djibouti Franc" + }, + "DKK": { + "symbol": "\u006b\u0072", + "num": 208, + "name": "Danish Krone" + }, + "DOP": { + "symbol": "\u0024", + "num": 214, + "name": "Dominican Peso" + }, + "DZD": { + "symbol": "\u062f\u002e\u062c", + "num": 12, + "name": "Algerian Dinar" + }, + "EGP": { + "symbol": "\u00a3", + "num": 818, + "name": "Egyptian Pound" + }, + "ERN": { + "symbol": "\u004e\u0066\u006b", + "num": 232, + "name": "Eritrean Nakfa" + }, + "ETB": { + "symbol": "\u0042\u0072", + "num": 230, + "name": "Ethiopian Birr" + }, + "EUR": { + "symbol": "\u20AC", + "num": 978, + "name": "Euro" + }, + "FJD": { + "symbol": "\u0024", + "num": 242, + "name": "Fiji Dollar" + }, + "FKP": { + "symbol": "\u00a3", + "num": 238, + "name": "Falkland Islands Pound" + }, + "GBP": { + "symbol": "\u00a3", + "num": 826, + "name": "Pound Sterling" + }, + "GEL": { + "symbol": "\u10da", + "num": 981, + "name": "Georgian Lari" + }, + "GHS": { + "symbol": "\u20b5", + "num": 936, + "name": "Ghanaian Cedi" + }, + "GIP": { + "symbol": "\u00a3", + "num": 292, + "name": "Gibraltar Pound" + }, + "GMD": { + "symbol": "\u0044", + "num": 270, + "name": "Gambian Dalasi" + }, + "GNF": { + "symbol": "\u20A3", + "num": 324, + "name": "Guinea Franc" + }, + "GTQ": { + "symbol": "\u0051", + "num": 320, + "name": "Guatemalan Quetzal" + }, + "GYD": { + "symbol": "\u0024", + "num": 328, + "name": "Guyana Dollar" + }, + "HKD": { + "symbol": "\u0024", + "num": 344, + "name": "Hong Kong Dollar" + }, + "HNL": { + "symbol": "\u004c", + "num": 340, + "name": "Honduran Lempira" + }, + "HRK": { + "symbol": "\u004b\u006e", + "num": 191, + "name": "Croatian Kuna" + }, + "HTG": { + "symbol": "\u004b\u006e", + "num": 332, + "name": "Haitian Gourde" + }, + "HUF": { + "symbol": "\u0046\u0074", + "num": 348, + "name": "Hungarian Forint" + }, + "IDR": { + "symbol": "\u0052\u0070", + "num": 360, + "name": "Indonesian Rupiah" + }, + "ILS": { + "symbol": "\u20aa", + "num": 376, + "name": "New Israeli Shekel" + }, + "INR": { + "symbol": "\u20b9", + "num": 356, + "name": "Indian Rupee" + }, + "IQD": { + "symbol": "\u0639\u002e\u062f", + "num": 368, + "name": "" + }, + "IRR": { + "symbol": "\ufdfc", + "num": 364, + "name": "Iranian Rial" + }, + "ISK": { + "symbol": "\u004b\u0072", + "num": 352, + "name": "Iceland Krona" + }, + "JMD": { + "symbol": "\u0024", + "num": 388, + "name": "Jamaican Dollar" + }, + "JOD": { + "symbol": "\u062f\u002e\u0627", + "num": 400, + "name": "Jordanian Dinar" + }, + "JPY": { + "symbol": "\u00a5", + "num": 392, + "name": "Japanese Yen" + }, + "KES": { + "symbol": "\u0053\u0068", + "num": 404, + "name": "Kenyan Shilling" + }, + "KGS": { + "symbol": "\u0441\u043e\u043c", + "num": 417, + "name": "Kyrgyzstani Som" + }, + "KHR": { + "symbol": "\u17db", + "num": 116, + "name": "Cambodian Riel" + }, + "KPW": { + "symbol": "\u20a9", + "num": 408, + "name": "North Korean Won" + }, + "KRW": { + "symbol": "\u20a9", + "num": 410, + "name": "South Korean Won" + }, + "KWD": { + "symbol": "\u062f\u002e\u0643", + "num": 414, + "name": "Kuwaiti Dinar" + }, + "KYD": { + "symbol": "\u0024", + "num": 136, + "name": "Cayman Islands Dollar" + }, + "KZT": { + "symbol": "\u3012", + "num": 398, + "name": "Kazakhstani Tenge" + }, + "LAK": { + "symbol": "\u20ad", + "num": 418, + "name": "Laotian Kip" + }, + "LBP": { + "symbol": "\u0644\u002e\u0644", + "num": 422, + "name": "Lebanese Pound" + }, + "LKR": { + "symbol": "\u0052\u0073", + "num": 144, + "name": "Sri Lanka Rupee" + }, + "LRD": { + "symbol": "\u0024", + "num": 430, + "name": "Liberian Dollar" + }, + "LSL": { + "symbol": "\u004c", + "num": 426, + "name": "Lesotho Loti" + }, + "LYD": { + "symbol": "\u0644\u002e\u062f", + "num": 434, + "name": "Libyan Dinar" + }, + "MAD": { + "symbol": "\u062f\u002e\u0645.", + "num": 504, + "name": "Moroccan Dirham" + }, + "MDL": { + "symbol": "\u004c", + "num": 498, + "name": "Moldavian Leu" + }, + "MGA": { + "symbol": "\u0041\u0072", + "num": 969, + "name": "Malagasy Ariary" + }, + "MKD": { + "symbol": "\u0434\u0435\u043d", + "num": 807, + "name": "Macedonian Denar" + }, + "MMK": { + "symbol": "\u004b", + "num": 104, + "name": "Myanmar Kyat" + }, + "MNT": { + "symbol": "\u20ae", + "num": 496, + "name": "Mongolian Tugrik" + }, + "MOP": { + "symbol": "\u0050", + "num": 446, + "name": "Macanese Pataca" + }, + "MRO": { + "symbol": "\u0055\u004d", + "num": 478, + "name": "Mauritanian Ouguiya" + }, + "MUR": { + "symbol": "\u20a8", + "num": 480, + "name": "Mauritius Rupee" + }, + "MVR": { + "symbol": "\u0783\u002e", + "num": 462, + "name": "Maldivan Rufiyaa" + }, + "MWK": { + "symbol": "\u004d\u004b", + "num": 454, + "name": "Malawian Kwacha" + }, + "MXN": { + "symbol": "\u0024", + "num": 484, + "name": "Mexican Peso" + }, + "MYR": { + "symbol": "\u0052\u004d", + "num": 458, + "name": "Malaysian Ringgit" + }, + "MZN": { + "symbol": "\u004d\u0054\u006e", + "num": 943, + "name": "Mozambican Metical" + }, + "NAD": { + "symbol": "\u0024", + "num": 516, + "name": "Namibia Dollar" + }, + "NGN": { + "symbol": "\u20a6", + "num": 566, + "name": "Nigerian Naira" + }, + "NIO": { + "symbol": "C\u0024", + "num": 558, + "name": "Nicaraguan Cordoba Oro" + }, + "NOK": { + "symbol": "\u006b\u0072", + "num": 578, + "name": "Norwegian Krone" + }, + "NPR": { + "symbol": "\u20a8", + "num": 524, + "name": "Nepalese Rupee" + }, + "NZD": { + "symbol": "\u0024", + "num": 554, + "name": "New Zealand Dollar" + }, + "OMR": { + "symbol": "\u0631\u002e\u0639\u002e", + "num": 512, + "name": "Rial Omani" + }, + "PAB": { + "symbol": "\u0042\u002f\u002e", + "num": 590, + "name": "Panaman Balboa" + }, + "PEN": { + "symbol": "\u0053\u002f\u002e", + "num": 604, + "name": "Peruvian Nuevo Sol" + }, + "PGK": { + "symbol": "\u004b", + "num": 598, + "name": "Papua New Guinean Kina" + }, + "PHP": { + "symbol": "\u20b1", + "num": 608, + "name": "Philippine Peso" + }, + "PKR": { + "symbol": "\u20a8", + "num": 586, + "name": "Pakistan Rupee" + }, + "PLN": { + "symbol": "\u007a\u0142", + "num": 985, + "name": "Polish Zloty" + }, + "PYG": { + "symbol": "\u20b2", + "num": 600, + "name": "Paraguayan Guarani" + }, + "QAR": { + "symbol": "\u0631\u002e\u0642", + "num": 634, + "name": "Qatari Rial" + }, + "RON": { + "symbol": "\u004c", + "num": 946, + "name": "Romania Leu" + }, + "RSD": { + "symbol": "\u0064\u0069\u006e", + "num": 941, + "name": "Serbian Dinar" + }, + "RUB": { + "symbol": "\u20bd", + "num": 643, + "name": "Russian Ruble" + }, + "RWF": { + "symbol": "\u20A3", + "num": 646, + "name": "Rwanda Franc" + }, + "SAR": { + "symbol": "\u0631\u002e\u0633", + "num": 682, + "name": "Saudi Riyal" + }, + "SBD": { + "symbol": "\u0024", + "num": 90, + "name": "Solomon Islands Dollar" + }, + "SCR": { + "symbol": "\u20a8", + "num": 690, + "name": "Seychelles Rupee" + }, + "SDG": { + "symbol": "\u00a3", + "num": 938, + "name": "Sudanese Pound" + }, + "SEK": { + "symbol": "\u006b\u0072", + "num": 752, + "name": "Swedish Krona" + }, + "SGD": { + "symbol": "\u0024", + "num": 702, + "name": "Singapore Dollar" + }, + "SHP": { + "symbol": "\u00a3", + "num": 654, + "name": "Saint Helena Pound" + }, + "SLL": { + "symbol": "\u004c\u0065", + "num": 694, + "name": "Sierra Leonean Leone" + }, + "SOS": { + "symbol": "\u0053\u0068", + "num": 706, + "name": "Somali Shilling" + }, + "SRD": { + "symbol": "\u0024", + "num": 968, + "name": "Suriname Dollar" + }, + "STD": { + "symbol": "\u0044\u0062", + "num": 678, + "name": "Sao Tome and Principe Dobra" + }, + "SYP": { + "symbol": "\u0644\u002e\u0633", + "num": 760, + "name": "Syrian Pound" + }, + "SZL": { + "symbol": "\u004c", + "num": 748, + "name": "Swazi Lilangeni" + }, + "THB": { + "symbol": "\u0e3f", + "num": 764, + "name": "Thai Baht" + }, + "TJS": { + "symbol": "\u0405\u041c", + "num": 972, + "name": "Tajikistani Somoni" + }, + "TMT": { + "symbol": "\u006d", + "num": 934, + "name": "Turkmenistan Manat" + }, + "TND": { + "symbol": "\u062f\u002e\u062a", + "num": 788, + "name": "Tunisian Dinar" + }, + "TOP": { + "symbol": "T\u0024", + "num": 776, + "name": "Tongan Pa’anga" + }, + "TRY": { + "symbol": "\u20a4", + "num": 949, + "name": "Turkish Lira" + }, + "TTD": { + "symbol": "\u0024", + "num": 780, + "name": "Trinidad and Tobago Dollar" + }, + "TWD": { + "symbol": "\u0024", + "num": 901, + "name": "Taiwan Dollar" + }, + "TZS": { + "symbol": "\u0053\u0068", + "num": 834, + "name": "Tanzanian Shilling" + }, + "UAH": { + "symbol": "\u20b4", + "num": 980, + "name": "Ukrainian Hryvnia" + }, + "UGX": { + "symbol": "\u0053\u0068", + "num": 800, + "name": "Uganda Shilling" + }, + "USD": { + "symbol": "\u0024", + "num": 840, + "name": "US Dollar" + }, + "UYU": { + "symbol": "\u0024", + "num": 858, + "name": "Uruguayan Peso" + }, + "UZS": { + "symbol": "\u0441\u045e\u043c", + "num": 860, + "name": "Uzbekistan Sum" + }, + "VEF": { + "symbol": "\u0042\u0073 \u0046", + "num": 937, + "name": "Venezuelan Bolivar Fuerte" + }, + "VND": { + "symbol": "\u20ab", + "num": 704, + "name": "Vietnamese Dong" + }, + "VUV": { + "symbol": "\u0056\u0074", + "num": 548, + "name": "Vanuatu Vatu" + }, + "WST": { + "symbol": "\u0054", + "num": 882, + "name": "Samoan Tala" + }, + "XAF": { + "symbol": "\u20A3", + "num": 950, + "name": "CFA Franc BCEAO" + }, + "XCD": { + "symbol": "\u0024", + "num": 951, + "name": "East Caribbean Dollar" + }, + "XPF": { + "symbol": "\u20A3", + "num": 953, + "name": "CFP Franc" + }, + "YER": { + "symbol": "\ufdfc", + "num": 886, + "name": "Yemeni Rial" + }, + "ZAR": { + "symbol": "\u0052", + "num": 710, + "name": "Rand" + }, + "ZMW": { + "symbol": "\u005a\u004b", + "num": 967, + "name": "Zambian Kwacha" + }, + "ZWL": { + "symbol": "\u0024", + "num": 932, + "name": "Zimbabwe Dollar" + } +} diff --git a/data/currencies_de_DE.csv b/data/currencies_de_DE.csv deleted file mode 100644 index 9c01701..0000000 --- a/data/currencies_de_DE.csv +++ /dev/null @@ -1,170 +0,0 @@ -"code","name" -"XUA", "ADB-Rechnungseinheit" -"AFN", "Afghani" -"DZD", "Algerischer Dinar" -"ARS", "Argentinischer Peso" -"AMD", "Armenian Dram" -"AWG", "Aruban Florin" -"AZN", "Aserbaidschan Manat" -"AUD", "Australischer Dollar" -"BSD", "Bahama-Dollar" -"BHD", "Bahrain-Dinar" -"THB", "Baht" -"PAB", "Balboa" -"BBD", "Barbados Dollar" -"BZD", "Belize Dollar" -"BMD", "Bermudian Dollar" -"BOB", "Boliviano" -"VES", "Bolívar Soberano" -"BRL", "Brasilianischer Real" -"BND", "Brunei Dollar" -"BGN", "Bulgarischer Lew" -"BIF", "Burundi Franc" -"CVE", "Cabo Verde Escudo" -"KYD", "Cayman Islands Dollar" -"XOF", "CFA Franc BCEAO" -"XAF", "CFA Franc BEAC" -"XPF", "CFP Franc" -"CLP", "Chilenischer Peso" -"KMF", "Comorian Franc" -"BAM", "Convertible Mark" -"NIO", "Cordoba Oro" -"CRC", "Costa Rica Colon" -"GMD", "Dalasi" -"MKD", "Denar" -"DJF", "Djibouti Franc" -"STN", "Dobra" -"DOP", "Dominikanischer Peso" -"VND", "Dong" -"DKK", "Dänische Krone" -"SVC", "El Salvador Colon" -"ETB", "Ethiopian Birr" -"EUR", "Euro" -"FKP", "Falkland Islands Pound" -"FJD", "Fidschi-Dollar" -"HUF", "Forint" -"GHS", "Ghana Cedi" -"GIP", "Gibraltar Pound" -"HTG", "Gourde" -"UAH", "Griwna" -"PYG", "Guarani" -"GNF", "Guinean Franc" -"GYD", "Guyana Dollar" -"HKD", "Hong Kong Dollar" -"ISK", "Iceland Krona" -"INR", "Indische Rupie" -"IQD", "Irakischer Dinar" -"IRR", "iranischer Rial" -"JMD", "Jamaikanischer Dollar" -"JOD", "Jordanischer Dinar" -"CAD", "Kanadischer Dollar" -"KES", "Kenianischer Schilling" -"PGK", "Kina" -"COP", "Kolumbianischer Peso" -"CDF", "Kongolesischer Franc" -"CUP", "Kubanischer Peso" -"HRK", "Kuna" -"KWD", "Kuwait Dinar" -"AOA", "Kwanza" -"MMK", "Kyat" -"LAK", "Lao Kip" -"GEL", "Lari" -"ALL", "Lek" -"HNL", "Lempira" -"SLL", "Leone" -"LBP", "Libanesisches Pfund" -"LRD", "Liberianischer Dollar" -"LYD", "Libyscher Dinar" -"SZL", "Lilangeni" -"LSL", "Loti" -"MGA", "Madagassisches Ariary" -"MWK", "Malawi Kwacha" -"MYR", "Malaysischer Ringgit" -"MAD", "Marokkanischer Dirham" -"MUR", "Mauritius-Rupie" -"MXV", "Mexican Unidad de Inversion (UDI)" -"MXN", "Mexikanischer Peso" -"MDL", "Moldovan Leu" -"MZN", "Mozambique Metical" -"BOV", "Mvdol" -"NGN", "Naira" -"ERN", "Nakfa" -"NAD", "Namibia Dollar" -"NPR", "Nepalesische Rupie" -"ILS", "New Israeli Sheqel" -"TWD", "New Taiwan Dollar" -"NZD", "New Zealand Dollar" -"BTN", "Ngultrum" -"ANG", "Niederländische Antillen Gulden" -"KPW", "Nordkoreanischer Won" -"NOK", "Norwegische Krone" -"XCD", "Ostkaribischer Dollar" -"MRU", "Ouguiya" -"PKR", "Pakistan Rupee" -"MOP", "Pataca" -"TOP", "Pa’anga" -"CUC", "Peso Cabrio" -"UYU", "Peso Uruguayo" -"GBP", "Pfund Sterling" -"PHP", "Philippinischer Peso" -"BWP", "Pula" -"QAR", "Qatari Rial" -"GTQ", "Quetzal" -"ZAR", "Rand" -"OMR", "Rial Omani" -"KHR", "Riel" -"RWF", "Ruanda Franc" -"MVR", "Rufiyaa" -"RON", "Rumänischer Leu" -"IDR", "Rupiah" -"RUB", "Russischer Rubel" -"SHP", "Saint Helena Pound" -"SBD", "Salomonen-Dollar" -"ZMW", "Sambian Kwacha" -"SAR", "Saudi Riyal" -"SEK", "Schwedische Krone" -"CHF", "Schweizer Franken" -"XDR", "SDR (Special Drawing Right)" -"RSD", "Serbischer Dinar" -"SCR", "Seychellen-Rupie" -"ZWL", "Simbabwe-Dollar" -"SGD", "Singapur-Dollar" -"PEN", "Sol" -"KGS", "Som" -"SOS", "Somali Shilling" -"TJS", "Somoni" -"LKR", "Sri Lanka Rupie" -"XSU", "Sucre" -"SDG", "Sudanesisches Pfund" -"SRD", "Surinam Dollar" -"SYP", "Syrisches Pfund" -"SSP", "Südsudanesisches Pfund" -"BDT", "Taka" -"WST", "Tala" -"TZS", "Tansanischer Schilling" -"KZT", "Tenge" -"TTD", "Trinidad und Tobago-Dollar" -"CZK", "Tschechische Krone" -"MNT", "Tugrik" -"TND", "Tunesischer Dinar" -"TMT", "Turkmenistan New Manat" -"TRY", "Türkische Lira" -"UGX", "Uganda Shilling" -"CLF", "Unidad de Fomento" -"COU", "Unidad de Valor Real" -"UYW", "Unidad Previsional" -"UYI", "Uruguay Peso en Unidades Indexadas (UI)" -"USN", "US-Dollar (nächster Tag)" -"USD", "US-Dollar" -"UZS", "Usbekistan Summe" -"AED", "VAE Dirham" -"VUV", "Vatu" -"BYN", "Weißrussischer Rubel" -"CHE", "WIR Euro" -"CHW", "WIR Franc" -"KRW", "Won" -"YER", "Yemeni Rial" -"JPY", "Yen" -"CNY", "Yuan Renminbi" -"PLN", "Zloty" -"EGP", "Ägyptisches Pfund" diff --git a/data/currencies_de_DE.json b/data/currencies_de_DE.json deleted file mode 100644 index e902df8..0000000 --- a/data/currencies_de_DE.json +++ /dev/null @@ -1,509 +0,0 @@ -{ - "XUA": { - "name": "ADB-Rechnungseinheit" - }, - "AFN": { - "name": "Afghani" - }, - "DZD": { - "name": "Algerischer Dinar" - }, - "ARS": { - "name": "Argentinischer Peso" - }, - "AMD": { - "name": "Armenian Dram" - }, - "AWG": { - "name": "Aruban Florin" - }, - "AZN": { - "name": "Aserbaidschan Manat" - }, - "AUD": { - "name": "Australischer Dollar" - }, - "BSD": { - "name": "Bahama-Dollar" - }, - "BHD": { - "name": "Bahrain-Dinar" - }, - "THB": { - "name": "Baht" - }, - "PAB": { - "name": "Balboa" - }, - "BBD": { - "name": "Barbados Dollar" - }, - "BZD": { - "name": "Belize Dollar" - }, - "BMD": { - "name": "Bermudian Dollar" - }, - "BOB": { - "name": "Boliviano" - }, - "VES": { - "name": "Bolívar Soberano" - }, - "BRL": { - "name": "Brasilianischer Real" - }, - "BND": { - "name": "Brunei Dollar" - }, - "BGN": { - "name": "Bulgarischer Lew" - }, - "BIF": { - "name": "Burundi Franc" - }, - "CVE": { - "name": "Cabo Verde Escudo" - }, - "KYD": { - "name": "Cayman Islands Dollar" - }, - "XOF": { - "name": "CFA Franc BCEAO" - }, - "XAF": { - "name": "CFA Franc BEAC" - }, - "XPF": { - "name": "CFP Franc" - }, - "CLP": { - "name": "Chilenischer Peso" - }, - "KMF": { - "name": "Comorian Franc" - }, - "BAM": { - "name": "Convertible Mark" - }, - "NIO": { - "name": "Cordoba Oro" - }, - "CRC": { - "name": "Costa Rica Colon" - }, - "GMD": { - "name": "Dalasi" - }, - "MKD": { - "name": "Denar" - }, - "DJF": { - "name": "Djibouti Franc" - }, - "STN": { - "name": "Dobra" - }, - "DOP": { - "name": "Dominikanischer Peso" - }, - "VND": { - "name": "Dong" - }, - "DKK": { - "name": "Dänische Krone" - }, - "SVC": { - "name": "El Salvador Colon" - }, - "ETB": { - "name": "Ethiopian Birr" - }, - "EUR": { - "name": "Euro" - }, - "FKP": { - "name": "Falkland Islands Pound" - }, - "FJD": { - "name": "Fidschi-Dollar" - }, - "HUF": { - "name": "Forint" - }, - "GHS": { - "name": "Ghana Cedi" - }, - "GIP": { - "name": "Gibraltar Pound" - }, - "HTG": { - "name": "Gourde" - }, - "UAH": { - "name": "Griwna" - }, - "PYG": { - "name": "Guarani" - }, - "GNF": { - "name": "Guinean Franc" - }, - "GYD": { - "name": "Guyana Dollar" - }, - "HKD": { - "name": "Hong Kong Dollar" - }, - "ISK": { - "name": "Iceland Krona" - }, - "INR": { - "name": "Indische Rupie" - }, - "IQD": { - "name": "Irakischer Dinar" - }, - "IRR": { - "name": "iranischer Rial" - }, - "JMD": { - "name": "Jamaikanischer Dollar" - }, - "JOD": { - "name": "Jordanischer Dinar" - }, - "CAD": { - "name": "Kanadischer Dollar" - }, - "KES": { - "name": "Kenianischer Schilling" - }, - "PGK": { - "name": "Kina" - }, - "COP": { - "name": "Kolumbianischer Peso" - }, - "CDF": { - "name": "Kongolesischer Franc" - }, - "CUP": { - "name": "Kubanischer Peso" - }, - "HRK": { - "name": "Kuna" - }, - "KWD": { - "name": "Kuwait Dinar" - }, - "AOA": { - "name": "Kwanza" - }, - "MMK": { - "name": "Kyat" - }, - "LAK": { - "name": "Lao Kip" - }, - "GEL": { - "name": "Lari" - }, - "ALL": { - "name": "Lek" - }, - "HNL": { - "name": "Lempira" - }, - "SLL": { - "name": "Leone" - }, - "LBP": { - "name": "Libanesisches Pfund" - }, - "LRD": { - "name": "Liberianischer Dollar" - }, - "LYD": { - "name": "Libyscher Dinar" - }, - "SZL": { - "name": "Lilangeni" - }, - "LSL": { - "name": "Loti" - }, - "MGA": { - "name": "Madagassisches Ariary" - }, - "MWK": { - "name": "Malawi Kwacha" - }, - "MYR": { - "name": "Malaysischer Ringgit" - }, - "MAD": { - "name": "Marokkanischer Dirham" - }, - "MUR": { - "name": "Mauritius-Rupie" - }, - "MXV": { - "name": "Mexican Unidad de Inversion (UDI)" - }, - "MXN": { - "name": "Mexikanischer Peso" - }, - "MDL": { - "name": "Moldovan Leu" - }, - "MZN": { - "name": "Mozambique Metical" - }, - "BOV": { - "name": "Mvdol" - }, - "NGN": { - "name": "Naira" - }, - "ERN": { - "name": "Nakfa" - }, - "NAD": { - "name": "Namibia Dollar" - }, - "NPR": { - "name": "Nepalesische Rupie" - }, - "ILS": { - "name": "New Israeli Sheqel" - }, - "TWD": { - "name": "New Taiwan Dollar" - }, - "NZD": { - "name": "New Zealand Dollar" - }, - "BTN": { - "name": "Ngultrum" - }, - "ANG": { - "name": "Niederländische Antillen Gulden" - }, - "KPW": { - "name": "Nordkoreanischer Won" - }, - "NOK": { - "name": "Norwegische Krone" - }, - "XCD": { - "name": "Ostkaribischer Dollar" - }, - "MRU": { - "name": "Ouguiya" - }, - "PKR": { - "name": "Pakistan Rupee" - }, - "MOP": { - "name": "Pataca" - }, - "TOP": { - "name": "Pa’anga" - }, - "CUC": { - "name": "Peso Cabrio" - }, - "UYU": { - "name": "Peso Uruguayo" - }, - "GBP": { - "name": "Pfund Sterling" - }, - "PHP": { - "name": "Philippinischer Peso" - }, - "BWP": { - "name": "Pula" - }, - "QAR": { - "name": "Qatari Rial" - }, - "GTQ": { - "name": "Quetzal" - }, - "ZAR": { - "name": "Rand" - }, - "OMR": { - "name": "Rial Omani" - }, - "KHR": { - "name": "Riel" - }, - "RWF": { - "name": "Ruanda Franc" - }, - "MVR": { - "name": "Rufiyaa" - }, - "RON": { - "name": "Rumänischer Leu" - }, - "IDR": { - "name": "Rupiah" - }, - "RUB": { - "name": "Russischer Rubel" - }, - "SHP": { - "name": "Saint Helena Pound" - }, - "SBD": { - "name": "Salomonen-Dollar" - }, - "ZMW": { - "name": "Sambian Kwacha" - }, - "SAR": { - "name": "Saudi Riyal" - }, - "SEK": { - "name": "Schwedische Krone" - }, - "CHF": { - "name": "Schweizer Franken" - }, - "XDR": { - "name": "SDR (Special Drawing Right)" - }, - "RSD": { - "name": "Serbischer Dinar" - }, - "SCR": { - "name": "Seychellen-Rupie" - }, - "ZWL": { - "name": "Simbabwe-Dollar" - }, - "SGD": { - "name": "Singapur-Dollar" - }, - "PEN": { - "name": "Sol" - }, - "KGS": { - "name": "Som" - }, - "SOS": { - "name": "Somali Shilling" - }, - "TJS": { - "name": "Somoni" - }, - "LKR": { - "name": "Sri Lanka Rupie" - }, - "XSU": { - "name": "Sucre" - }, - "SDG": { - "name": "Sudanesisches Pfund" - }, - "SRD": { - "name": "Surinam Dollar" - }, - "SYP": { - "name": "Syrisches Pfund" - }, - "SSP": { - "name": "Südsudanesisches Pfund" - }, - "BDT": { - "name": "Taka" - }, - "WST": { - "name": "Tala" - }, - "TZS": { - "name": "Tansanischer Schilling" - }, - "KZT": { - "name": "Tenge" - }, - "TTD": { - "name": "Trinidad und Tobago-Dollar" - }, - "CZK": { - "name": "Tschechische Krone" - }, - "MNT": { - "name": "Tugrik" - }, - "TND": { - "name": "Tunesischer Dinar" - }, - "TMT": { - "name": "Turkmenistan New Manat" - }, - "TRY": { - "name": "Türkische Lira" - }, - "UGX": { - "name": "Uganda Shilling" - }, - "CLF": { - "name": "Unidad de Fomento" - }, - "COU": { - "name": "Unidad de Valor Real" - }, - "UYW": { - "name": "Unidad Previsional" - }, - "UYI": { - "name": "Uruguay Peso en Unidades Indexadas (UI)" - }, - "USN": { - "name": "US-Dollar (nächster Tag)" - }, - "USD": { - "name": "US-Dollar" - }, - "UZS": { - "name": "Usbekistan Summe" - }, - "AED": { - "name": "VAE Dirham" - }, - "VUV": { - "name": "Vatu" - }, - "BYN": { - "name": "Weißrussischer Rubel" - }, - "CHE": { - "name": "WIR Euro" - }, - "CHW": { - "name": "WIR Franc" - }, - "KRW": { - "name": "Won" - }, - "YER": { - "name": "Yemeni Rial" - }, - "JPY": { - "name": "Yen" - }, - "CNY": { - "name": "Yuan Renminbi" - }, - "PLN": { - "name": "Zloty" - }, - "EGP": { - "name": "Ägyptisches Pfund" - } -} diff --git a/data/currencies_de_DE.txt b/data/currencies_de_DE.txt deleted file mode 100644 index 4da3385..0000000 --- a/data/currencies_de_DE.txt +++ /dev/null @@ -1,169 +0,0 @@ -"XUA", "ADB-Rechnungseinheit" -"AFN", "Afghani" -"DZD", "Algerischer Dinar" -"ARS", "Argentinischer Peso" -"AMD", "Armenian Dram" -"AWG", "Aruban Florin" -"AUD", "Australischer Dollar" -"AZN", "Aserbaidschan Manat" -"BSD", "Bahama-Dollar" -"BHD", "Bahrain-Dinar" -"THB", "Baht" -"PAB", "Balboa" -"BBD", "Barbados Dollar" -"BYN", "Weißrussischer Rubel" -"BZD", "Belize Dollar" -"BMD", "Bermudian Dollar" -"BOB", "Boliviano" -"VES", "Bolívar Soberano" -"BRL", "Brasilianischer Real" -"BND", "Brunei Dollar" -"BGN", "Bulgarischer Lew" -"BIF", "Burundi Franc" -"XOF", "CFA Franc BCEAO" -"XAF", "CFA Franc BEAC" -"XPF", "CFP Franc" -"CVE", "Cabo Verde Escudo" -"CAD", "Kanadischer Dollar" -"KYD", "Cayman Islands Dollar" -"CLP", "Chilenischer Peso" -"COP", "Kolumbianischer Peso" -"KMF", "Comorian Franc" -"CDF", "Kongolesischer Franc" -"BAM", "Convertible Mark" -"NIO", "Cordoba Oro" -"CRC", "Costa Rica Colon" -"CUP", "Kubanischer Peso" -"CZK", "Tschechische Krone" -"GMD", "Dalasi" -"DKK", "Dänische Krone" -"MKD", "Denar" -"DJF", "Djibouti Franc" -"STN", "Dobra" -"DOP", "Dominikanischer Peso" -"VND", "Dong" -"XCD", "Ostkaribischer Dollar" -"EGP", "Ägyptisches Pfund" -"SVC", "El Salvador Colon" -"ETB", "Ethiopian Birr" -"EUR", "Euro" -"FKP", "Falkland Islands Pound" -"FJD", "Fidschi-Dollar" -"HUF", "Forint" -"GHS", "Ghana Cedi" -"GIP", "Gibraltar Pound" -"HTG", "Gourde" -"PYG", "Guarani" -"GNF", "Guinean Franc" -"GYD", "Guyana Dollar" -"HKD", "Hong Kong Dollar" -"UAH", "Griwna" -"ISK", "Iceland Krona" -"INR", "Indische Rupie" -"IRR", "iranischer Rial" -"IQD", "Irakischer Dinar" -"JMD", "Jamaikanischer Dollar" -"JOD", "Jordanischer Dinar" -"KES", "Kenianischer Schilling" -"PGK", "Kina" -"HRK", "Kuna" -"KWD", "Kuwait Dinar" -"AOA", "Kwanza" -"MMK", "Kyat" -"LAK", "Lao Kip" -"GEL", "Lari" -"LBP", "Libanesisches Pfund" -"ALL", "Lek" -"HNL", "Lempira" -"SLL", "Leone" -"LRD", "Liberianischer Dollar" -"LYD", "Libyscher Dinar" -"SZL", "Lilangeni" -"LSL", "Loti" -"MGA", "Madagassisches Ariary" -"MWK", "Malawi Kwacha" -"MYR", "Malaysischer Ringgit" -"MUR", "Mauritius-Rupie" -"MXN", "Mexikanischer Peso" -"MXV", "Mexican Unidad de Inversion (UDI)" -"MDL", "Moldovan Leu" -"MAD", "Marokkanischer Dirham" -"MZN", "Mozambique Metical" -"BOV", "Mvdol" -"NGN", "Naira" -"ERN", "Nakfa" -"NAD", "Namibia Dollar" -"NPR", "Nepalesische Rupie" -"ANG", "Niederländische Antillen Gulden" -"ILS", "New Israeli Sheqel" -"TWD", "New Taiwan Dollar" -"NZD", "New Zealand Dollar" -"BTN", "Ngultrum" -"KPW", "Nordkoreanischer Won" -"NOK", "Norwegische Krone" -"MRU", "Ouguiya" -"PKR", "Pakistan Rupee" -"MOP", "Pataca" -"TOP", "Pa’anga" -"CUC", "Peso Cabrio" -"UYU", "Peso Uruguayo" -"PHP", "Philippinischer Peso" -"GBP", "Pfund Sterling" -"BWP", "Pula" -"QAR", "Qatari Rial" -"GTQ", "Quetzal" -"ZAR", "Rand" -"OMR", "Rial Omani" -"KHR", "Riel" -"RON", "Rumänischer Leu" -"MVR", "Rufiyaa" -"IDR", "Rupiah" -"RUB", "Russischer Rubel" -"RWF", "Ruanda Franc" -"XDR", "SDR (Special Drawing Right)" -"SHP", "Saint Helena Pound" -"SAR", "Saudi Riyal" -"RSD", "Serbischer Dinar" -"SCR", "Seychellen-Rupie" -"SGD", "Singapur-Dollar" -"PEN", "Sol" -"SBD", "Salomonen-Dollar" -"KGS", "Som" -"SOS", "Somali Shilling" -"TJS", "Somoni" -"SSP", "Südsudanesisches Pfund" -"LKR", "Sri Lanka Rupie" -"XSU", "Sucre" -"SDG", "Sudanesisches Pfund" -"SRD", "Surinam Dollar" -"SEK", "Schwedische Krone" -"CHF", "Schweizer Franken" -"SYP", "Syrisches Pfund" -"BDT", "Taka" -"WST", "Tala" -"TZS", "Tansanischer Schilling" -"KZT", "Tenge" -"TTD", "Trinidad und Tobago-Dollar" -"MNT", "Tugrik" -"TND", "Tunesischer Dinar" -"TRY", "Türkische Lira" -"TMT", "Turkmenistan New Manat" -"AED", "VAE Dirham" -"USN", "US-Dollar (nächster Tag)" -"USD", "US-Dollar" -"UGX", "Uganda Shilling" -"UYW", "Unidad Previsional" -"CLF", "Unidad de Fomento" -"COU", "Unidad de Valor Real" -"UYI", "Uruguay Peso en Unidades Indexadas (UI)" -"UZS", "Usbekistan Summe" -"VUV", "Vatu" -"CHE", "WIR Euro" -"CHW", "WIR Franc" -"KRW", "Won" -"YER", "Yemeni Rial" -"JPY", "Yen" -"CNY", "Yuan Renminbi" -"ZMW", "Sambian Kwacha" -"ZWL", "Simbabwe-Dollar" -"PLN", "Zloty" diff --git a/data/currencies_en_GB.json b/data/currencies_en_GB.json deleted file mode 100644 index cbdf036..0000000 --- a/data/currencies_en_GB.json +++ /dev/null @@ -1,509 +0,0 @@ -{ - "XUA": { - "name": "ADB Unit of Account" - }, - "AFN": { - "name": "Afghani" - }, - "DZD": { - "name": "Algerian Dinar" - }, - "ARS": { - "name": "Argentine Peso" - }, - "AMD": { - "name": "Armenian Dram" - }, - "AWG": { - "name": "Aruban Florin" - }, - "AUD": { - "name": "Australian Dollar" - }, - "AZN": { - "name": "Azerbaijan Manat" - }, - "BSD": { - "name": "Bahamian Dollar" - }, - "BHD": { - "name": "Bahraini Dinar" - }, - "THB": { - "name": "Baht" - }, - "PAB": { - "name": "Balboa" - }, - "BBD": { - "name": "Barbados Dollar" - }, - "BYN": { - "name": "Belarusian Ruble" - }, - "BZD": { - "name": "Belize Dollar" - }, - "BMD": { - "name": "Bermudian Dollar" - }, - "BOB": { - "name": "Boliviano" - }, - "VES": { - "name": "Bolívar Soberano" - }, - "BRL": { - "name": "Brazilian Real" - }, - "BND": { - "name": "Brunei Dollar" - }, - "BGN": { - "name": "Bulgarian Lev" - }, - "BIF": { - "name": "Burundi Franc" - }, - "XOF": { - "name": "CFA Franc BCEAO" - }, - "XAF": { - "name": "CFA Franc BEAC" - }, - "XPF": { - "name": "CFP Franc" - }, - "CVE": { - "name": "Cabo Verde Escudo" - }, - "CAD": { - "name": "Canadian Dollar" - }, - "KYD": { - "name": "Cayman Islands Dollar" - }, - "CLP": { - "name": "Chilean Peso" - }, - "COP": { - "name": "Colombian Peso" - }, - "KMF": { - "name": "Comorian Franc " - }, - "CDF": { - "name": "Congolese Franc" - }, - "BAM": { - "name": "Convertible Mark" - }, - "NIO": { - "name": "Cordoba Oro" - }, - "CRC": { - "name": "Costa Rican Colon" - }, - "CUP": { - "name": "Cuban Peso" - }, - "CZK": { - "name": "Czech Koruna" - }, - "GMD": { - "name": "Dalasi" - }, - "DKK": { - "name": "Danish Krone" - }, - "MKD": { - "name": "Denar" - }, - "DJF": { - "name": "Djibouti Franc" - }, - "STN": { - "name": "Dobra" - }, - "DOP": { - "name": "Dominican Peso" - }, - "VND": { - "name": "Dong" - }, - "XCD": { - "name": "East Caribbean Dollar" - }, - "EGP": { - "name": "Egyptian Pound" - }, - "SVC": { - "name": "El Salvador Colon" - }, - "ETB": { - "name": "Ethiopian Birr" - }, - "EUR": { - "name": "Euro" - }, - "FKP": { - "name": "Falkland Islands Pound" - }, - "FJD": { - "name": "Fiji Dollar" - }, - "HUF": { - "name": "Forint" - }, - "GHS": { - "name": "Ghana Cedi" - }, - "GIP": { - "name": "Gibraltar Pound" - }, - "HTG": { - "name": "Gourde" - }, - "PYG": { - "name": "Guarani" - }, - "GNF": { - "name": "Guinean Franc" - }, - "GYD": { - "name": "Guyana Dollar" - }, - "HKD": { - "name": "Hong Kong Dollar" - }, - "UAH": { - "name": "Hryvnia" - }, - "ISK": { - "name": "Iceland Krona" - }, - "INR": { - "name": "Indian Rupee" - }, - "IRR": { - "name": "Iranian Rial" - }, - "IQD": { - "name": "Iraqi Dinar" - }, - "JMD": { - "name": "Jamaican Dollar" - }, - "JOD": { - "name": "Jordanian Dinar" - }, - "KES": { - "name": "Kenyan Shilling" - }, - "PGK": { - "name": "Kina" - }, - "HRK": { - "name": "Kuna" - }, - "KWD": { - "name": "Kuwaiti Dinar" - }, - "AOA": { - "name": "Kwanza" - }, - "MMK": { - "name": "Kyat" - }, - "LAK": { - "name": "Lao Kip" - }, - "GEL": { - "name": "Lari" - }, - "LBP": { - "name": "Lebanese Pound" - }, - "ALL": { - "name": "Lek" - }, - "HNL": { - "name": "Lempira" - }, - "SLL": { - "name": "Leone" - }, - "LRD": { - "name": "Liberian Dollar" - }, - "LYD": { - "name": "Libyan Dinar" - }, - "SZL": { - "name": "Lilangeni" - }, - "LSL": { - "name": "Loti" - }, - "MGA": { - "name": "Malagasy Ariary" - }, - "MWK": { - "name": "Malawi Kwacha" - }, - "MYR": { - "name": "Malaysian Ringgit" - }, - "MUR": { - "name": "Mauritius Rupee" - }, - "MXN": { - "name": "Mexican Peso" - }, - "MXV": { - "name": "Mexican Unidad de Inversion (UDI)" - }, - "MDL": { - "name": "Moldovan Leu" - }, - "MAD": { - "name": "Moroccan Dirham" - }, - "MZN": { - "name": "Mozambique Metical" - }, - "BOV": { - "name": "Mvdol" - }, - "NGN": { - "name": "Naira" - }, - "ERN": { - "name": "Nakfa" - }, - "NAD": { - "name": "Namibia Dollar" - }, - "NPR": { - "name": "Nepalese Rupee" - }, - "ANG": { - "name": "Netherlands Antillean Guilder" - }, - "ILS": { - "name": "New Israeli Sheqel" - }, - "TWD": { - "name": "New Taiwan Dollar" - }, - "NZD": { - "name": "New Zealand Dollar" - }, - "BTN": { - "name": "Ngultrum" - }, - "KPW": { - "name": "North Korean Won" - }, - "NOK": { - "name": "Norwegian Krone" - }, - "MRU": { - "name": "Ouguiya" - }, - "PKR": { - "name": "Pakistan Rupee" - }, - "MOP": { - "name": "Pataca" - }, - "TOP": { - "name": "Pa’anga" - }, - "CUC": { - "name": "Peso Convertible" - }, - "UYU": { - "name": "Peso Uruguayo" - }, - "PHP": { - "name": "Philippine Peso" - }, - "GBP": { - "name": "Pound Sterling" - }, - "BWP": { - "name": "Pula" - }, - "QAR": { - "name": "Qatari Rial" - }, - "GTQ": { - "name": "Quetzal" - }, - "ZAR": { - "name": "Rand" - }, - "OMR": { - "name": "Rial Omani" - }, - "KHR": { - "name": "Riel" - }, - "RON": { - "name": "Romanian Leu" - }, - "MVR": { - "name": "Rufiyaa" - }, - "IDR": { - "name": "Rupiah" - }, - "RUB": { - "name": "Russian Ruble" - }, - "RWF": { - "name": "Rwanda Franc" - }, - "XDR": { - "name": "SDR (Special Drawing Right)" - }, - "SHP": { - "name": "Saint Helena Pound" - }, - "SAR": { - "name": "Saudi Riyal" - }, - "RSD": { - "name": "Serbian Dinar" - }, - "SCR": { - "name": "Seychelles Rupee" - }, - "SGD": { - "name": "Singapore Dollar" - }, - "PEN": { - "name": "Sol" - }, - "SBD": { - "name": "Solomon Islands Dollar" - }, - "KGS": { - "name": "Som" - }, - "SOS": { - "name": "Somali Shilling" - }, - "TJS": { - "name": "Somoni" - }, - "SSP": { - "name": "South Sudanese Pound" - }, - "LKR": { - "name": "Sri Lanka Rupee" - }, - "XSU": { - "name": "Sucre" - }, - "SDG": { - "name": "Sudanese Pound" - }, - "SRD": { - "name": "Surinam Dollar" - }, - "SEK": { - "name": "Swedish Krona" - }, - "CHF": { - "name": "Swiss Franc" - }, - "SYP": { - "name": "Syrian Pound" - }, - "BDT": { - "name": "Taka" - }, - "WST": { - "name": "Tala" - }, - "TZS": { - "name": "Tanzanian Shilling" - }, - "KZT": { - "name": "Tenge" - }, - "TTD": { - "name": "Trinidad and Tobago Dollar" - }, - "MNT": { - "name": "Tugrik" - }, - "TND": { - "name": "Tunisian Dinar" - }, - "TRY": { - "name": "Turkish Lira" - }, - "TMT": { - "name": "Turkmenistan New Manat" - }, - "AED": { - "name": "UAE Dirham" - }, - "USN": { - "name": "US Dollar (Next day)" - }, - "USD": { - "name": "US Dollar" - }, - "UGX": { - "name": "Uganda Shilling" - }, - "UYW": { - "name": "Unidad Previsional" - }, - "CLF": { - "name": "Unidad de Fomento" - }, - "COU": { - "name": "Unidad de Valor Real" - }, - "UYI": { - "name": "Uruguay Peso en Unidades Indexadas (UI)" - }, - "UZS": { - "name": "Uzbekistan Sum" - }, - "VUV": { - "name": "Vatu" - }, - "CHE": { - "name": "WIR Euro" - }, - "CHW": { - "name": "WIR Franc" - }, - "KRW": { - "name": "Won" - }, - "YER": { - "name": "Yemeni Rial" - }, - "JPY": { - "name": "Yen" - }, - "CNY": { - "name": "Yuan Renminbi" - }, - "ZMW": { - "name": "Zambian Kwacha" - }, - "ZWL": { - "name": "Zimbabwe Dollar" - }, - "PLN": { - "name": "Zloty" - } -} diff --git a/data/currencies_fi_FI.csv b/data/currencies_fi_FI.csv deleted file mode 100644 index b446606..0000000 --- a/data/currencies_fi_FI.csv +++ /dev/null @@ -1,170 +0,0 @@ -"code","name" -"XUA", "ADB laskentayksikkö" -"AFN", "afgaani" -"ANG", "Alankomaiden Antillien guldeni" -"DZD", "Algerian dinaari" -"ARS", "Argentiinan peso" -"AMD", "Armenian Dram" -"AWG", "Aruban Florin" -"AUD", "Australian dollari" -"AZN", "Azerbaidzan Manat" -"BSD", "Bahaman dollari" -"BHD", "Bahrainin dinaari" -"THB", "baht" -"PAB", "Balboa" -"BBD", "Barbadoksen dollari" -"BZD", "Belisen dollari" -"BMD", "Bermudian dollari" -"ROP", "Boliviano" -"VES", "Bolívar Soberano" -"BRL", "Brasilian real" -"BND", "Brunein dollari" -"BGN", "Bulgarian lev" -"BIF", "Burundi Franc" -"CVE", "Cabo Verde Escudo" -"KYD", "Caymansaarten dollari" -"XOF", "CFA Franc BCEAO" -"XAF", "CFA Franc BEAC" -"XPF", "CFP Franc" -"CLP", "Chilen peso" -"NIO", "Cordoba Oro" -"CRC", "Costa Rican Colon" -"GMD", "Dalasi" -"MKD", "Denar" -"DJF", "Djibouti Franc" -"STN", "Dobra" -"DOP", "Dominikaaninen peso" -"Dongia", "Dong" -"EGP", "Egyptin punta" -"SVC", "El Salvador Colon" -"GBP", "Englannin punta" -"SSP", "Etelä-Sudanin punta" -"ETB", "Etiopian Birr" -"EUR", "Euro" -"FKP", "Falklandinsaarten punta" -"FJD", "Fidžin dollari" -"PHP", "Filippiinien peso" -"HUF", "forintti" -"GHS", "Ghana Cedi" -"GIP", "Gibraltarin punta" -"HTG", "Gourde" -"PYG", "guarani" -"GNF", "Guinean frangi" -"GYD", "Guyanan dollari" -"HKD", "Hongkongin dollari" -"UAH", "Hryvnia" -"INR", "intialainen rupia" -"IQD", "Irakin dinaari" -"IRR", "Iranian Rial" -"ISK", "Islannin kruunu" -"XCD", "Itä-Karibian dollari" -"JMD", "Jamaikan dollari" -"YER", "Jemen Rial" -"JOD", "Jordanian dinaari" -"CAD", "Kanadan dollari" -"KES", "Kenian shilling" -"PGK", "Kiina" -"COP", "Kolumbian peso" -"KMF", "Komorien frangi" -"CDF", "Kongon ranska" -"HRK", "Kuna" -"CUP", "Kuuban peso" -"KWD", "Kuwaitin dinaari" -"AOA", "Kwanza" -"MMK", "Kyat" -"LAK", "Lao Kip" -"GEL", "Lari" -"Kaikki", "Lek" -"HNL", "Lempira" -"SLL", "Leone" -"LBP", "Libanonin punta" -"LRD", "Liberian dollari" -"LYD", "Libyan dinaari" -"SZL", "Lilangeni" -"LSL", "Loti" -"MGA", "Madagaskarin ariary" -"MWK", "Malawi Kwacha" -"MYR", "Malaysian Ringgit" -"MAD", "marokkolainen dirham" -"MUR", "Mauritiuksen rupia" -"MXN", "Meksikon peso" -"MXV", "Meksikon Unidad de Inversion (UDI)" -"MDL", "Moldovan leu" -"MZN", "Mosambik Metical" -"BOV", "Mvdol" -"NGN", "Naira" -"ERN", "Nakfa" -"NAD", "Namibian dollari" -"NPR", "Nepalin rupia" -"BTN", "Ngultrum" -"NOK", "Norjan kruunu" -"MRU", "Ouguiya" -"TOP", "Pa'anga" -"PKR", "Pakistanin rupia" -"MOP", "Pataca" -"CUC", "Peso Convertible" -"UYU", "Peso Uruguayo" -"KPW", "Pohjois-Korean voitto" -"BWP", "Pula" -"QAR", "Qatari Rial" -"GTQ", "Quetzal" -"ZAR", "Rand" -"OMR", "Rial Omani" -"KHR", "Riel" -"RON", "Romanian leu" -"MVR", "Rufiyaa" -"SEK", "Ruotsin kruunu" -"IDR", "rupia" -"RWF", "Rwanda Franc" -"SHP", "Saint Helena Pound" -"SBD", "Salomonsaarten dollari" -"ZMW", "Sambia Kwacha" -"SAR", "Saudi Riyal" -"XDR", "SDR (erityinen piirustus oikealla)" -"RSD", "serbialainen dinaari" -"SCR", "Seychellien rupia" -"SGD", "Singaporen dollari" -"PEN", "Sol" -"KGS", "Som" -"SOS", "Somalian šilinki" -"TJS", "Somoni" -"LKR", "Sri Lankan rupia" -"XSU", "Sucre" -"SDG", "Sudanin punta" -"SRD", "Surinamin dollari" -"CHF", "Sveitsin frangi" -"SYP", "Syyrian punta" -"BDT", "Taka" -"WST", "Tala" -"TZS", "Tansanian šillinki" -"DKK", "Tanskan kruunu" -"KZT", "Tenge" -"TTD", "Trinidadin ja Tobagon dollari" -"MNT", "tugrik" -"TND", "Tunisian dinaari" -"Yritä", "Turkin liira" -"TMT", "Turkmenistan New Manat" -"CZK", "tšekin koruna" -"AED", "UAE dirham" -"UGX", "Ugandan šillinki" -"CLF", "Unidad de Fomento" -"COU", "Unidad de Valor Real" -"UYW", "Unidad Previsional" -"UYI", "Uruguay Peso en Unidades Indexadas (UI)" -"NZD", "Uuden-Seelannin dollari" -"ILS", "uusi israelilainen sekeli" -"TWD", "uusi Taiwanin dollari" -"UZS", "Uzbekistan Sum" -"BAM", "Vaihdettava merkki" -"BYN", "Valkovenäjän rupla" -"VUV", "vatu" -"RUB", "Venäjän rupla" -"KRW", "voitti" -"CHE", "WIR Euro" -"CHW", "WIR Franc" -"JPY", "Yen" -"USN", "Yhdysvaltain dollari (seuraavana päivänä)" -"USD", "Yhdysvaltain dollari" -"CNY", "Yuan Renminbi" -"ZWL", "Zimbabwen dollari" -"PLN", "zloty" diff --git a/data/currencies_fi_FI.json b/data/currencies_fi_FI.json deleted file mode 100644 index 77f796c..0000000 --- a/data/currencies_fi_FI.json +++ /dev/null @@ -1,509 +0,0 @@ -{ - "XUA": { - "name": "ADB laskentayksikkö" - }, - "AFN": { - "name": "afgaani" - }, - "ANG": { - "name": "Alankomaiden Antillien guldeni" - }, - "DZD": { - "name": "Algerian dinaari" - }, - "ARS": { - "name": "Argentiinan peso" - }, - "AMD": { - "name": "Armenian Dram" - }, - "AWG": { - "name": "Aruban Florin" - }, - "AUD": { - "name": "Australian dollari" - }, - "AZN": { - "name": "Azerbaidzan Manat" - }, - "BSD": { - "name": "Bahaman dollari" - }, - "BHD": { - "name": "Bahrainin dinaari" - }, - "THB": { - "name": "baht" - }, - "PAB": { - "name": "Balboa" - }, - "BBD": { - "name": "Barbadoksen dollari" - }, - "BZD": { - "name": "Belisen dollari" - }, - "BMD": { - "name": "Bermudian dollari" - }, - "ROP": { - "name": "Boliviano" - }, - "VES": { - "name": "Bolívar Soberano" - }, - "BRL": { - "name": "Brasilian real" - }, - "BND": { - "name": "Brunein dollari" - }, - "BGN": { - "name": "Bulgarian lev" - }, - "BIF": { - "name": "Burundi Franc" - }, - "CVE": { - "name": "Cabo Verde Escudo" - }, - "KYD": { - "name": "Caymansaarten dollari" - }, - "XOF": { - "name": "CFA Franc BCEAO" - }, - "XAF": { - "name": "CFA Franc BEAC" - }, - "XPF": { - "name": "CFP Franc" - }, - "CLP": { - "name": "Chilen peso" - }, - "NIO": { - "name": "Cordoba Oro" - }, - "CRC": { - "name": "Costa Rican Colon" - }, - "GMD": { - "name": "Dalasi" - }, - "MKD": { - "name": "Denar" - }, - "DJF": { - "name": "Djibouti Franc" - }, - "STN": { - "name": "Dobra" - }, - "DOP": { - "name": "Dominikaaninen peso" - }, - "Dongia": { - "name": "Dong" - }, - "EGP": { - "name": "Egyptin punta" - }, - "SVC": { - "name": "El Salvador Colon" - }, - "GBP": { - "name": "Englannin punta" - }, - "SSP": { - "name": "Etelä-Sudanin punta" - }, - "ETB": { - "name": "Etiopian Birr" - }, - "EUR": { - "name": "Euro" - }, - "FKP": { - "name": "Falklandinsaarten punta" - }, - "FJD": { - "name": "Fidžin dollari" - }, - "PHP": { - "name": "Filippiinien peso" - }, - "HUF": { - "name": "forintti" - }, - "GHS": { - "name": "Ghana Cedi" - }, - "GIP": { - "name": "Gibraltarin punta" - }, - "HTG": { - "name": "Gourde" - }, - "PYG": { - "name": "guarani" - }, - "GNF": { - "name": "Guinean frangi" - }, - "GYD": { - "name": "Guyanan dollari" - }, - "HKD": { - "name": "Hongkongin dollari" - }, - "UAH": { - "name": "Hryvnia" - }, - "INR": { - "name": "intialainen rupia" - }, - "IQD": { - "name": "Irakin dinaari" - }, - "IRR": { - "name": "Iranian Rial" - }, - "ISK": { - "name": "Islannin kruunu" - }, - "XCD": { - "name": "Itä-Karibian dollari" - }, - "JMD": { - "name": "Jamaikan dollari" - }, - "YER": { - "name": "Jemen Rial" - }, - "JOD": { - "name": "Jordanian dinaari" - }, - "CAD": { - "name": "Kanadan dollari" - }, - "KES": { - "name": "Kenian shilling" - }, - "PGK": { - "name": "Kiina" - }, - "COP": { - "name": "Kolumbian peso" - }, - "KMF": { - "name": "Komorien frangi" - }, - "CDF": { - "name": "Kongon ranska" - }, - "HRK": { - "name": "Kuna" - }, - "CUP": { - "name": "Kuuban peso" - }, - "KWD": { - "name": "Kuwaitin dinaari" - }, - "AOA": { - "name": "Kwanza" - }, - "MMK": { - "name": "Kyat" - }, - "LAK": { - "name": "Lao Kip" - }, - "GEL": { - "name": "Lari" - }, - "Kaikki": { - "name": "Lek" - }, - "HNL": { - "name": "Lempira" - }, - "SLL": { - "name": "Leone" - }, - "LBP": { - "name": "Libanonin punta" - }, - "LRD": { - "name": "Liberian dollari" - }, - "LYD": { - "name": "Libyan dinaari" - }, - "SZL": { - "name": "Lilangeni" - }, - "LSL": { - "name": "Loti" - }, - "MGA": { - "name": "Madagaskarin ariary" - }, - "MWK": { - "name": "Malawi Kwacha" - }, - "MYR": { - "name": "Malaysian Ringgit" - }, - "MAD": { - "name": "marokkolainen dirham" - }, - "MUR": { - "name": "Mauritiuksen rupia" - }, - "MXN": { - "name": "Meksikon peso" - }, - "MXV": { - "name": "Meksikon Unidad de Inversion (UDI)" - }, - "MDL": { - "name": "Moldovan leu" - }, - "MZN": { - "name": "Mosambik Metical" - }, - "BOV": { - "name": "Mvdol" - }, - "NGN": { - "name": "Naira" - }, - "ERN": { - "name": "Nakfa" - }, - "NAD": { - "name": "Namibian dollari" - }, - "NPR": { - "name": "Nepalin rupia" - }, - "BTN": { - "name": "Ngultrum" - }, - "NOK": { - "name": "Norjan kruunu" - }, - "MRU": { - "name": "Ouguiya" - }, - "TOP": { - "name": "Pa'anga" - }, - "PKR": { - "name": "Pakistanin rupia" - }, - "MOP": { - "name": "Pataca" - }, - "CUC": { - "name": "Peso Convertible" - }, - "UYU": { - "name": "Peso Uruguayo" - }, - "KPW": { - "name": "Pohjois-Korean voitto" - }, - "BWP": { - "name": "Pula" - }, - "QAR": { - "name": "Qatari Rial" - }, - "GTQ": { - "name": "Quetzal" - }, - "ZAR": { - "name": "Rand" - }, - "OMR": { - "name": "Rial Omani" - }, - "KHR": { - "name": "Riel" - }, - "RON": { - "name": "Romanian leu" - }, - "MVR": { - "name": "Rufiyaa" - }, - "SEK": { - "name": "Ruotsin kruunu" - }, - "IDR": { - "name": "rupia" - }, - "RWF": { - "name": "Rwanda Franc" - }, - "SHP": { - "name": "Saint Helena Pound" - }, - "SBD": { - "name": "Salomonsaarten dollari" - }, - "ZMW": { - "name": "Sambia Kwacha" - }, - "SAR": { - "name": "Saudi Riyal" - }, - "XDR": { - "name": "SDR (erityinen piirustus oikealla)" - }, - "RSD": { - "name": "serbialainen dinaari" - }, - "SCR": { - "name": "Seychellien rupia" - }, - "SGD": { - "name": "Singaporen dollari" - }, - "PEN": { - "name": "Sol" - }, - "KGS": { - "name": "Som" - }, - "SOS": { - "name": "Somalian šilinki" - }, - "TJS": { - "name": "Somoni" - }, - "LKR": { - "name": "Sri Lankan rupia" - }, - "XSU": { - "name": "Sucre" - }, - "SDG": { - "name": "Sudanin punta" - }, - "SRD": { - "name": "Surinamin dollari" - }, - "CHF": { - "name": "Sveitsin frangi" - }, - "SYP": { - "name": "Syyrian punta" - }, - "BDT": { - "name": "Taka" - }, - "WST": { - "name": "Tala" - }, - "TZS": { - "name": "Tansanian šillinki" - }, - "DKK": { - "name": "Tanskan kruunu" - }, - "KZT": { - "name": "Tenge" - }, - "TTD": { - "name": "Trinidadin ja Tobagon dollari" - }, - "MNT": { - "name": "tugrik" - }, - "TND": { - "name": "Tunisian dinaari" - }, - "Yritä": { - "name": "Turkin liira" - }, - "TMT": { - "name": "Turkmenistan New Manat" - }, - "CZK": { - "name": "tšekin koruna" - }, - "AED": { - "name": "UAE dirham" - }, - "UGX": { - "name": "Ugandan šillinki" - }, - "CLF": { - "name": "Unidad de Fomento" - }, - "COU": { - "name": "Unidad de Valor Real" - }, - "UYW": { - "name": "Unidad Previsional" - }, - "UYI": { - "name": "Uruguay Peso en Unidades Indexadas (UI)" - }, - "NZD": { - "name": "Uuden-Seelannin dollari" - }, - "ILS": { - "name": "uusi israelilainen sekeli" - }, - "TWD": { - "name": "uusi Taiwanin dollari" - }, - "UZS": { - "name": "Uzbekistan Sum" - }, - "BAM": { - "name": "Vaihdettava merkki" - }, - "BYN": { - "name": "Valkovenäjän rupla" - }, - "VUV": { - "name": "vatu" - }, - "RUB": { - "name": "Venäjän rupla" - }, - "KRW": { - "name": "voitti" - }, - "CHE": { - "name": "WIR Euro" - }, - "CHW": { - "name": "WIR Franc" - }, - "JPY": { - "name": "Yen" - }, - "USN": { - "name": "Yhdysvaltain dollari (seuraavana päivänä)" - }, - "USD": { - "name": "Yhdysvaltain dollari" - }, - "CNY": { - "name": "Yuan Renminbi" - }, - "ZWL": { - "name": "Zimbabwen dollari" - }, - "PLN": { - "name": "zloty" - } -} diff --git a/data/currencies_fi_FI.txt b/data/currencies_fi_FI.txt deleted file mode 100644 index c6b7f79..0000000 --- a/data/currencies_fi_FI.txt +++ /dev/null @@ -1,169 +0,0 @@ -"XUA", "ADB laskentayksikkö" -"AFN", "afgaani" -"DZD", "Algerian dinaari" -"ARS", "Argentiinan peso" -"AMD", "Armenian Dram" -"AWG", "Aruban Florin" -"AUD", "Australian dollari" -"AZN", "Azerbaidzan Manat" -"BSD", "Bahaman dollari" -"BHD", "Bahrainin dinaari" -"THB", "baht" -"PAB", "Balboa" -"BBD", "Barbadoksen dollari" -"BYN", "Valkovenäjän rupla" -"BZD", "Belisen dollari" -"BMD", "Bermudian dollari" -"ROP", "Boliviano" -"VES", "Bolívar Soberano" -"BRL", "Brasilian real" -"BND", "Brunein dollari" -"BGN", "Bulgarian lev" -"BIF", "Burundi Franc" -"XOF", "CFA Franc BCEAO" -"XAF", "CFA Franc BEAC" -"XPF", "CFP Franc" -"CVE", "Cabo Verde Escudo" -"CAD", "Kanadan dollari" -"KYD", "Caymansaarten dollari" -"CLP", "Chilen peso" -"COP", "Kolumbian peso" -"KMF", "Komorien frangi" -"CDF", "Kongon ranska" -"BAM", "Vaihdettava merkki" -"NIO", "Cordoba Oro" -"CRC", "Costa Rican Colon" -"CUP", "Kuuban peso" -"CZK", "tšekin koruna" -"GMD", "Dalasi" -"DKK", "Tanskan kruunu" -"MKD", "Denar" -"DJF", "Djibouti Franc" -"STN", "Dobra" -"DOP", "Dominikaaninen peso" -"Dongia", "Dong" -"XCD", "Itä-Karibian dollari" -"EGP", "Egyptin punta" -"SVC", "El Salvador Colon" -"ETB", "Etiopian Birr" -"EUR", "Euro" -"FKP", "Falklandinsaarten punta" -"FJD", "Fidžin dollari" -"HUF", "forintti" -"GHS", "Ghana Cedi" -"GIP", "Gibraltarin punta" -"HTG", "Gourde" -"PYG", "guarani" -"GNF", "Guinean frangi" -"GYD", "Guyanan dollari" -"HKD", "Hongkongin dollari" -"UAH", "Hryvnia" -"ISK", "Islannin kruunu" -"INR", "intialainen rupia" -"IRR", "Iranian Rial" -"IQD", "Irakin dinaari" -"JMD", "Jamaikan dollari" -"JOD", "Jordanian dinaari" -"KES", "Kenian shilling" -"PGK", "Kiina" -"HRK", "Kuna" -"KWD", "Kuwaitin dinaari" -"AOA", "Kwanza" -"MMK", "Kyat" -"LAK", "Lao Kip" -"GEL", "Lari" -"LBP", "Libanonin punta" -"Kaikki", "Lek" -"HNL", "Lempira" -"SLL", "Leone" -"LRD", "Liberian dollari" -"LYD", "Libyan dinaari" -"SZL", "Lilangeni" -"LSL", "Loti" -"MGA", "Madagaskarin ariary" -"MWK", "Malawi Kwacha" -"MYR", "Malaysian Ringgit" -"MUR", "Mauritiuksen rupia" -"MXN", "Meksikon peso" -"MXV", "Meksikon Unidad de Inversion (UDI)" -"MDL", "Moldovan leu" -"MAD", "marokkolainen dirham" -"MZN", "Mosambik Metical" -"BOV", "Mvdol" -"NGN", "Naira" -"ERN", "Nakfa" -"NAD", "Namibian dollari" -"NPR", "Nepalin rupia" -"ANG", "Alankomaiden Antillien guldeni" -"ILS", "uusi israelilainen sekeli" -"TWD", "uusi Taiwanin dollari" -"NZD", "Uuden-Seelannin dollari" -"BTN", "Ngultrum" -"KPW", "Pohjois-Korean voitto" -"NOK", "Norjan kruunu" -"MRU", "Ouguiya" -"PKR", "Pakistanin rupia" -"MOP", "Pataca" -"TOP", "Pa'anga" -"CUC", "Peso Convertible" -"UYU", "Peso Uruguayo" -"PHP", "Filippiinien peso" -"GBP", "Englannin punta" -"BWP", "Pula" -"QAR", "Qatari Rial" -"GTQ", "Quetzal" -"ZAR", "Rand" -"OMR", "Rial Omani" -"KHR", "Riel" -"RON", "Romanian leu" -"MVR", "Rufiyaa" -"IDR", "rupia" -"RUB", "Venäjän rupla" -"RWF", "Rwanda Franc" -"XDR", "SDR (erityinen piirustus oikealla)" -"SHP", "Saint Helena Pound" -"SAR", "Saudi Riyal" -"RSD", "serbialainen dinaari" -"SCR", "Seychellien rupia" -"SGD", "Singaporen dollari" -"PEN", "Sol" -"SBD", "Salomonsaarten dollari" -"KGS", "Som" -"SOS", "Somalian šilinki" -"TJS", "Somoni" -"SSP", "Etelä-Sudanin punta" -"LKR", "Sri Lankan rupia" -"XSU", "Sucre" -"SDG", "Sudanin punta" -"SRD", "Surinamin dollari" -"SEK", "Ruotsin kruunu" -"CHF", "Sveitsin frangi" -"SYP", "Syyrian punta" -"BDT", "Taka" -"WST", "Tala" -"TZS", "Tansanian šillinki" -"KZT", "Tenge" -"TTD", "Trinidadin ja Tobagon dollari" -"MNT", "tugrik" -"TND", "Tunisian dinaari" -"Yritä", "Turkin liira" -"TMT", "Turkmenistan New Manat" -"AED", "UAE dirham" -"USN", "Yhdysvaltain dollari (seuraavana päivänä)" -"USD", "Yhdysvaltain dollari" -"UGX", "Ugandan šillinki" -"UYW", "Unidad Previsional" -"CLF", "Unidad de Fomento" -"COU", "Unidad de Valor Real" -"UYI", "Uruguay Peso en Unidades Indexadas (UI)" -"UZS", "Uzbekistan Sum" -"VUV", "vatu" -"CHE", "WIR Euro" -"CHW", "WIR Franc" -"KRW", "voitti" -"YER", "Jemen Rial" -"JPY", "Yen" -"CNY", "Yuan Renminbi" -"ZMW", "Sambia Kwacha" -"ZWL", "Zimbabwen dollari" -"PLN", "zloty" diff --git a/data/translation_procedure.txt b/data/translation_procedure.txt index 22bd258..3ddf767 100644 --- a/data/translation_procedure.txt +++ b/data/translation_procedure.txt @@ -1,16 +1,21 @@ Currency translation procedure: +Open "currencies.csv" +Cut the first line: "code", "symbol", "num","name" + Go to translate.google.com and translate "currencies.csv" to the needed language {LANG} e.g. "en_GB". -Save result as currencies_{LANG}.txt. -Check that all fields are enclosed bu double quotes and for any serious discrepancies. -Run `sort -f --field-separator=',' -k2 currencies_{LANG}.txt > currencies_{LANG}.csv` -Insert as first line: "code","name" +Save result as currencies_{LANG}.txt. NOTE: NOT ".csv" +Check that all fields are enclosed by double quotes and for any serious discrepancies. +Run `sort -f --field-separator=',' -k4 currencies_{LANG}.txt > currencies_{LANG}.csv` + +Insert as first line: "code", "symbol", "num","name" Go to http://www.convertcsv.com/csv-to-json.htm (Or similar service) -Upload/paste currencies_sort_by_name_{LANG}.csv. +Upload/paste currencies_{LANG}.csv. Encoding UTF-8 Input options: First row is column names. Check Generate output: CVS To Keyed JSON Save result as "currencies_{LANG}.json" +Check again that all fields are enclosed by double quotes and for any serious discrepancies. diff --git a/harbour-currencyconverter.pro b/harbour-currencyconverter.pro index b9b8e97..8c250de 100644 --- a/harbour-currencyconverter.pro +++ b/harbour-currencyconverter.pro @@ -1,3 +1,6 @@ TEMPLATE = subdirs SUBDIRS += app.pro # lib/fileproxy + +DISTFILES += \ + qml/components/Cache.qml diff --git a/qml/components/Cache.qml b/qml/components/Cache.qml new file mode 100644 index 0000000..c295083 --- /dev/null +++ b/qml/components/Cache.qml @@ -0,0 +1,97 @@ +/* +Copyright (c) 2019 Thomas Tanghus + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +import QtQuick 2.6 + +Storage { + id: storage + // TODO: This creates some weird path. + dbName: StandardPaths.data + tblName: 'rates' + // Use Map? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map + columns: ({ + fromCode: 'TEXT', + toCode: 'TEXT', + rate: 'TEXT', + date: 'TEXT' + }) + key: ['fromCode', 'toCode'] + + function setRate(from, to, rate, date) { + console.log('App.storage.setRate()', from, to, rate, date) + try { + set(['fromCode', 'toCode', 'rate', 'date'], + [from, to, rate, date]) + } catch(e) { + console.warn(e.message) + } + } + + function getRate(from, to, cb) { + console.log('App.storage.getRate(', from, to, ')') + if(!Env.isReady) { return } + try { + get(['*'], {'fromCode': from, 'toCode': to}, + function(rows) { cb(rows[0]) }) + } catch(e) { + console.warn(e.message) + console.trace() + } + } + + function removeRate(from, to, cb) { + console.log('App.storage.removeRate(', from, to, ')') + if(!Env.isReady) { return } + try { + // TODO: Return something useful instead of row + remove({'fromCode': from, 'toCode': to}, + function(rows) { cb(rows[0]) }) + } catch(e) { + console.warn(e.message) + console.trace() + } + } + + // NOTE: Without using 'base' 'rate' precision will be... Unlikely, BUT + // the timestamp will most likely cause it to be invalidated anyways, so... + function getAvailable(base, cb) { + try { + executeSQL('SELECT DISTINCT toCode AS code, rate FROM rates', + function(rows) { + console.log('App.storage.getAvailable(', base, ') Rows:', rows.length) + //console.log('App.storage.getAvailable:', JSON.stringify(rows)) + if(cb) { + cb(rows) + } + }) + } catch(e) { + console.warn(e.message) + console.trace() + } + } +} + diff --git a/qml/components/Currencies.qml b/qml/components/Currencies.qml new file mode 100644 index 0000000..260e8c0 --- /dev/null +++ b/qml/components/Currencies.qml @@ -0,0 +1,164 @@ +/* + Copyright (C) 2019 Thomas Tanghus + All rights reserved. + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +pragma Singleton + +import QtQuick 2.6 + +QtObject { + readonly property bool isReady: Boolean(all && available) + property var all + property var available + + //onAllChanged: isReady = Boolean(all && available) + //onAvailableChanged: isReady = Boolean(all && available) + + function createPair(pair) { + //console.log('Currencies.createPair:', JSON.stringify(pair)) + + if(!isReady) { + error('Cannot create CurrencyPairs at this moment:', pair) + return + } + + if(typeof pair !== 'object') { + error("I don't know what to do with", pair) + console.trace() + } else { + if(pair.length) { + // Can't do nothin' with an array + error('Cannot create a "CurrencyPair" from an "array":', pair) + return + } else if(pair.objectType && pair.objectType === 'Currency') { + error('Cannot create a "CurrencyPair" from a "Currency"') + return + } else if(pair.objectType && pair.objectType === 'CurrencyPair') { + // Return a new object to make sure it's initialized properly + return _createFromPair(pair) + } else { + // Try anyway + //console.warn('Creating "CurrencyPair" from unknown object!') + return _createFromPair(pair) + } + } + } + + function _createFromPair(pair) { + if(pair.hasOwnProperty('toCode') && pair.hasOwnProperty('fromCode')) { + // Then it's from the cache + pair['from'] = pair.fromCode + pair['to'] = pair.toCode + } + if(!pair.hasOwnProperty('from') || !pair.hasOwnProperty('to')) { + error('Not a CurrencyPair:' + JSON.stringify(pair)) + return + } + if(pair.objectType && pair.objectType === 'CurrencyPair') { + return pair.init(pair) + } + var component = Qt.createComponent(Qt.resolvedUrl('CurrencyPair.qml')); + + if (component.status === Component.Error) { + error(component.errorString()) + return + } + + var newPair = component.createObject() + newPair.init(pair) + return newPair + } + + function createCurrency(currency) { + //console.log('Currencies.createCurrency:', currency) + + if(!isReady) { + error('Cannot create Currencies at this moment:', currency) + return + } + + if(typeof currency === 'string') { + return _createFromCode(currency) + } else if(typeof currency === 'object') { + if(currency.length) { + // Can't do nothin' with an array + error('Cannot create a "Currency" from an "array":', currency) + return + } else if(currency.objectType && currency.objectType === 'CurrencyPair') { + error('Cannot create a "Currency" from a "CurrencyPair"') + return + } else if(currency.objectType && currency.objectType === 'Currency') { + // Return a new object to make sure it's initialized properly + return _createFromCurrency(currency) + } else { + // Try anyway + console.warn('Creating "Currency" from unknown object!') + return _createFromCurrency(currency) + } + } else { + error("I don't know what to do with", currency) + console.trace() + } + } + + function _createFromCurrency(currency) { + if(!currency.hasOwnProperty('code')) { + error('Not a Currency:' + JSON.stringify(currency)) + return + } + return currency.init(currency) + } + + function _createFromCode(code) { + if(code.trim().length !== 3) { + error('Not a Currency Code:' + code) + return + } + if(!all.hasOwnProperty(code)) { + error('Currency Code not found:' + code) + return + } + + var tmp = all[code] + var component = Qt.createComponent(Qt.resolvedUrl('Currency.qml')); + + if (component.status === Component.Error) { + error(component.errorString()) + return + } + + var newCurrency = component.createObject() + newCurrency.init(tmp) + return newCurrency + } + + function error(msg) { + console.error(msg) + console.trace() + } +} diff --git a/qml/components/Currency.qml b/qml/components/Currency.qml new file mode 100644 index 0000000..f9853b8 --- /dev/null +++ b/qml/components/Currency.qml @@ -0,0 +1,55 @@ +/* + Copyright (C) 2013-2019 Thomas Tanghus + All rights reserved. + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import QtQuick 2.6 + +QtObject { + readonly property string objectType: 'Currency' + readonly property string objectName: name + ' (' + code + ')' + property string code: '' + property string num: '' + property string name: '' + property string symbol: '' + property variant countries: [] + + function init(dict) { + code = dict.code + symbol = dict.symbol + name = dict.name + num = dict.num + } + + function getSymbol() { + return symbol || code + } + + function toString() { + return objectName + } +} diff --git a/qml/components/CurrencyCombo.qml b/qml/components/CurrencyCombo.qml index aeaec63..6034c78 100644 --- a/qml/components/CurrencyCombo.qml +++ b/qml/components/CurrencyCombo.qml @@ -1,5 +1,11 @@ /* - Copyright (C) 2013-2018 Thomas Tanghus + Originally from ValueButton.qml + Copyright (C) 2013 Jolla Ltd. + Contact: Bea Lam + All rights reserved. + + Modifications by: + Copyright (C) 2013-2019 Thomas Tanghus All rights reserved. You may use this file under the terms of BSD license as follows: @@ -29,57 +35,109 @@ import QtQuick 2.6 import Sailfish.Silica 1.0 +import '.' -ComboBox { +BackgroundItem { id: currencyCombo; - signal activated(Item currency, int idx) + signal activated(var currency) - property string currentCurrency - property bool ready: false + property alias label: titleText.text + property alias value: valueText.text + property var allCurrencies + property string currentCurrencyCode + property var currentCurrency + property var list + property alias _imagePath: flag.source + property int _duration: 200 - onCurrentCurrencyChanged: { - if(!ready) { - return - } + Binding { + target: currencyCombo + property: 'allCurrencies' + value: Currencies.all + } - console.log('Setting currency', currentCurrency); - if(typeof currentCurrency !== 'string' || currentCurrency.length !== 3) { - console.warn('Trying to set invalid currency', currentCurrency); - notifier.notify('Trying to set invalid currency:', currentCurrency) + Column { + id: column - return; + anchors { + left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter + leftMargin: currencyCombo.leftMargin; rightMargin: currencyCombo.rightMargin } + Flow { + id: row - // Use the children directly from the model as the menu isn't necessarily populated yet - var currencies = currencyModel.children; + spacing: Theme.paddingMedium + width: parent.width + move: Transition { + NumberAnimation { + properties: 'x,y'; easing.type: Easing.InOutQuad; duration: currencyCombo._duration + } + } + + Label { + id: titleText + color: currencyCombo.down ? Theme.highlightColor : Theme.primaryColor + width: Math.min(Math.round(parent.width*0.3) - Theme.paddingMedium) + height: text.length ? implicitHeight : 0 + horizontalAlignment: Text.AlignRight + fontSizeMode: Text.HorizontalFit + minimumPixelSize: Theme.fontSizeSmallBase + truncationMode: TruncationMode.Fade + } + + Image { + id: flag + source: '' + fillMode: Image.PreserveAspectFit + visible: source !== '' + height: parent.height + width: height + verticalAlignment: Image.AlignVCenter + } - for(var i = 0; i < currencies.length; i++ ) { - if(currencies[i].code === currentCurrency) { - currentItem = currencies[i]; - currencyCombo.activated(currentItem, i); - return; + Label { + id: valueText + color: Theme.highlightColor + truncationMode: TruncationMode.Fade } } } - Component.onCompleted: ready = true + onAllCurrenciesChanged: { + currentCurrency = allCurrencies[currentCurrencyCode] + setCurrentCurrency(currentCurrency) + } - menu: ContextMenu { - id: contextMenu; - Repeater { - model: currencyModel - } - onActivated: { - console.log('menu index: ', index) - console.log('menu parent: ', currencyCombo) - var currency = contextMenu.children[index]; - //currencyCombo.activated(currency); - currentCurrency = currency.code; + onClicked: { + list = pageStack.push(Qt.resolvedUrl('CurrencyList.qml')) + list.currencySelected.connect(setCurrentCurrency) + } + + onCurrentCurrencyCodeChanged: { + var allCurrencies = Currencies.all + + if(Env.isReady) { + currentCurrency = allCurrencies[currentCurrencyCode] + setCurrentCurrency(currentCurrency) } } - CurrencyModel { - id: currencyModel + function setCurrentCurrency(currency) { + console.log('CurrencyCombo.setCurrentCurrency', currency) + if(!currency) { + console.log('CurrencyCombo.setCurrentCurrency. Empty currency!!!', typeof currency) + console.trace() + return + } + + if(currentCurrencyCode && currentCurrencyCode !== currency.code) { + currentCurrencyCode = currency.code + } + value = currency.name + ' (' + currency.code + ')' + _imagePath = Qt.resolvedUrl("../../flags/" + currency.code.toLowerCase() + ".png") + if(!Env.isBusy && Env.isReady && currentCurrencyCode) { + currencyCombo.activated(currency) + } } } diff --git a/qml/components/CurrencyList.qml b/qml/components/CurrencyList.qml new file mode 100644 index 0000000..5dda6d5 --- /dev/null +++ b/qml/components/CurrencyList.qml @@ -0,0 +1,138 @@ +/* + Copyright (C) 2013-2019 Thomas Tanghus + All rights reserved. + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import QtQuick 2.6 +import Sailfish.Silica 1.0 + +Page { + id: searchPage + property string searchString + property bool keepSearchFieldFocus + signal currencySelected(var currency) + allowedOrientations: Orientation.All + + // Temporaryly giving up on searching + //onSearchStringChanged: currenciesModel.update() + Component.onCompleted: { + //currenciesModel.update() + } + + Column { + id: headerContainer + + width: searchPage.width + + PageHeader { + title: 'Currencies' + } + + /*SearchField { + id: searchField + width: parent.width + + Binding { + target: searchPage + property: "searchString" + value: searchField.text.toLowerCase().trim() + } + }*/ + } + + SilicaListView { + anchors { + fill: parent + topMargin: headerContainer.height + Theme.paddingLarge + } + signal currencySelected(var currency) + + VerticalScrollDecorator {} + + model: currenciesModel + delegate: currencyDelegate + } + + CurrencyModel { + id: currenciesModel + + /* + function findByCode(code) { + for(var i = 0; i < rowCount(); i++) { + if(model.get(i).code === code) { + return model.get(i) + } + } + return null + } + */ + } + + Component { + id: currencyDelegate + ListItem { + id: listItem + onClicked: { + console.log('CurrencyList.onClicked:', model.code, model.index) + currencySelected(model) + pageStack.pop() + } + + ListView.onAdd: AddAnimation { + target: listItem + } + ListView.onRemove: RemoveAnimation { + target: listItem + } + + Row { + spacing: Theme.paddingMedium + padding: Theme.paddingMedium + anchors { + left: parent.left + leftMargin: Theme.horizontalPageMargin + right: parent.right + rightMargin: Theme.horizontalPageMargin + verticalCenter: parent.verticalCenter + } + Image { + source: Qt.resolvedUrl("../../flags/" + model.code.toLowerCase() + ".png") + anchors.verticalCenter: parent.verticalCenter + fillMode: Image.PreserveAspectFit + } + Label { + anchors.verticalCenter: parent.verticalCenter + color: listItem.highlighted ? Theme.highlightColor : Theme.primaryColor + textFormat: Text.StyledText + text: model.name + ' (' + model.code + ')' + } + } + } + } +} + + diff --git a/qml/components/CurrencyModel.qml b/qml/components/CurrencyModel.qml index 86c83ed..ef5f7e6 100644 --- a/qml/components/CurrencyModel.qml +++ b/qml/components/CurrencyModel.qml @@ -28,165 +28,114 @@ */ import QtQuick 2.6 +import QtQml.Models 2.3 import Sailfish.Silica 1.0 +import '.' -VisualItemModel { +ListModel { id: currencyModel - CurrencyItem {code:'AFN'; numericCode:'971'; name:qsTr('Afghani'); countries: ['AFGHANISTAN']} - CurrencyItem {code:'DZD'; numericCode:'012'; name:qsTr('Algerian Dinar'); countries: ['ALGERIA']} - CurrencyItem {code:'ARS'; numericCode:'032'; name:qsTr('Argentine Peso'); countries: ['ARGENTINA']} - CurrencyItem {code:'AMD'; numericCode:'051'; name:qsTr('Armenian Dram'); countries: ['ARMENIA']} - CurrencyItem {code:'AWG'; numericCode:'533'; name:qsTr('Aruban Florin'); countries: ['ARUBA']} - CurrencyItem {code:'AUD'; numericCode:'036'; name:qsTr('Australian Dollar'); countries: ['AUSTRALIA', 'CHRISTMAS ISLAND', 'COCOS (KEELING) ISLANDS', 'HEARD ISLAND AND MCDONALD ISLANDS', 'KIRIBATI', 'NAURU', 'NORFOLK ISLAND', 'TUVALU']} - CurrencyItem {code:'AZN'; numericCode:'944'; name:qsTr('Azerbaijanian Manat'); countries: ['AZERBAIJAN']} - CurrencyItem {code:'BSD'; numericCode:'044'; name:qsTr('Bahamian Dollar'); countries: ['BAHAMAS']} - CurrencyItem {code:'BHD'; numericCode:'048'; name:qsTr('Bahraini Dinar'); countries: ['BAHRAIN']} - CurrencyItem {code:'THB'; numericCode:'764'; name:qsTr('Baht'); countries: ['THAILAND']} - CurrencyItem {code:'BBD'; numericCode:'052'; name:qsTr('Barbados Dollar'); countries: ['BARBADOS']} - CurrencyItem {code:'BND'; numericCode:'096'; name:qsTr('Brunei Dollar'); countries: ['BRUNEI DARUSSALAM']} - CurrencyItem {code:'BMD'; numericCode:'060'; name:qsTr('Bermudian Dollar'); countries: ['BERMUDA']} - CurrencyItem {code:'BYR'; numericCode:'974'; name:qsTr('Belarussian Ruble'); countries: ['BELARUS']} - CurrencyItem {code:'BZD'; numericCode:'084'; name:qsTr('Belize Dollar'); countries: ['BELIZE']} - CurrencyItem {code:'VEF'; numericCode:'937'; name:qsTr('Bolivar Fuerte'); countries: ['VENEZUELA']} - CurrencyItem {code:'BGN'; numericCode:'975'; name:qsTr('Bulgarian Lev'); countries: ['BULGARIA']} - CurrencyItem {code:'BIF'; numericCode:'108'; name:qsTr('Burundi Franc'); countries: ['BURUNDI']} - CurrencyItem {code:'BRL'; numericCode:'986'; name:qsTr('Brazilian Real'); countries: ['BRAZIL']} - CurrencyItem {code:'CAD'; numericCode:'124'; name:qsTr('Canadian Dollar'); countries: ['CANADA']} - CurrencyItem {code:'CVE'; numericCode:'132'; name:qsTr('Cape Verde Escudo'); countries: ['CAPE VERDE']} - CurrencyItem {code:'KYD'; numericCode:'136'; name:qsTr('Cayman Islands Dollar'); countries: ['CAYMAN ISLANDS']} - CurrencyItem {code:'XPF'; numericCode:'953'; name:qsTr('CFP Franc'); countries: ['FRENCH POLYNESIA', 'NEW CALEDONIA', 'WALLIS AND FUTUNA']} - CurrencyItem {code:'CZK'; numericCode:'203'; name:qsTr('Czech Koruna'); countries: ['CZECH REPUBLIC']} - CurrencyItem {code:'CLP'; numericCode:'152'; name:qsTr('Chilean Peso'); countries: ['CHILE']} - CurrencyItem {code:'KMF'; numericCode:'174'; name:qsTr('Comoro Franc'); countries: ['COMOROS']} - CurrencyItem {code:'BAM'; numericCode:'977'; name:qsTr('Convertible Marks'); countries: ['BOSNIA AND HERZEGOVINA']} - CurrencyItem {code:'NIO'; numericCode:'558'; name:qsTr('Cordoba Oro'); countries: ['NICARAGUA']} - CurrencyItem {code:'CRC'; numericCode:'188'; name:qsTr('Costa Rican Colon'); countries: ['COSTA RICA']} - CurrencyItem {code:'COP'; numericCode:'170'; name:qsTr('Colombian Peso'); countries: ['COSTA RICA']} - CurrencyItem {code:'HRK'; numericCode:'191'; name:qsTr('Croatian Kuna'); countries: ['CROATIA']} - CurrencyItem {code:'CUP'; numericCode:'192'; name:qsTr('Cuban Peso'); countries: ['CUBA']} - CurrencyItem {code:'GMD'; numericCode:'270'; name:qsTr('Dalasi'); countries: ['GAMBIA']} - CurrencyItem {code:'DKK'; numericCode:'208'; name:qsTr('Danish Krone'); countries: ['DENMARK', 'FAROE ISLANDS', 'GREENLAND']} - CurrencyItem {code:'MKD'; numericCode:'807'; name:qsTr('Denar'); countries: ['MACEDONIA']} - CurrencyItem {code:'DJF'; numericCode:'262'; name:qsTr('Djibouti Franc'); countries: ['DJIBOUTI']} - CurrencyItem {code:'DOP'; numericCode:'214'; name:qsTr('Dominican Peso'); countries: ['DOMINICAN REPUBLIC']} - CurrencyItem {code:'VND'; numericCode:'704'; name:qsTr('Dong'); countries: ['VIET NAM']} - CurrencyItem {code:'STD'; numericCode:'678'; name:qsTr('Dobra'); countries: ['SAO TOME AND PRINCIPE']} - CurrencyItem {code:'XCD'; numericCode:'951'; name:qsTr('East Caribbean Dollar'); countries: ['ANGUILLA', 'ANTIGUA AND BARBUDA', 'DOMINICA', 'GRENADA', 'MONTSERRAT', 'SAINT KITTS AND NEVIS', 'SAINT LUCIA', 'SAINT VINCENT AND THE GRENADINES']} - CurrencyItem {code:'EGP'; numericCode:'818'; name:qsTr('Egyptian Pound'); countries: ['EGYPT']} - CurrencyItem {code:'ETB'; numericCode:'230'; name:qsTr('Ethiopian Birr'); countries: ['ETHIOPIA']} - CurrencyItem {code:'EUR'; numericCode:'978'; name:qsTr('Euro'); symbol: "€"; countries: ['ANDORRA', 'AUSTRIA', 'BELGIUM', 'FINLAND', 'FRANCE', 'FRENCH GUIANA', 'FRENCH SOUTHERN TERRITORIES', 'GERMANY', 'GREECE', 'GUADELOUPE', 'IRELAND', 'ITALY', 'LUXEMBOURG', 'MARTINIQUE', 'MAYOTTE', 'MONACO', 'MONTENEGRO', 'NETHERLANDS', 'PORTUGAL', 'R.UNION', 'SAINT PIERRE AND MIQUELON', 'SAN MARINO', 'SLOVENIA', 'SPAIN']} - CurrencyItem {code:'FKP'; numericCode:'238'; name:qsTr('Falkland Islands Pound'); countries: ['FALKLAND ISLANDS (MALVINAS)']} - CurrencyItem {code:'FJD'; numericCode:'242'; name:qsTr('Fiji Dollar'); countries: ['FIJI']} - CurrencyItem {code:'HUF'; numericCode:'348'; name:qsTr('Forint'); countries: ['HUNGARY']} - CurrencyItem {code:'GHS'; numericCode:'936'; name:qsTr('Ghana Cedi'); countries: ['GHANA']} - CurrencyItem {code:'GIP'; numericCode:'292'; name:qsTr('Gibraltar Pound'); countries: ['GIBRALTAR']} - CurrencyItem {code:'XAU'; numericCode:'959'; name:qsTr('Gold'); countries: []} -// CurrencyItem {code:'XFO'; numericCode:'Nil'; name:qsTr('Gold-Franc'); countries: []} - CurrencyItem {code:'PYG'; numericCode:'600'; name:qsTr('Guarani'); countries: ['PARAGUAY']} - CurrencyItem {code:'GNF'; numericCode:'324'; name:qsTr('Guinea Franc'); countries: ['GUINEA']} - CurrencyItem {code:'GYD'; numericCode:'328'; name:qsTr('Guyana Dollar'); countries: ['GUYANA']} - CurrencyItem {code:'HKD'; numericCode:'344'; name:qsTr('Hong Kong Dollar'); countries: ['HONG KONG']} - CurrencyItem {code:'UAH'; numericCode:'980'; name:qsTr('Ukrainian Hryvna'); countries: ['UKRAINE']} - CurrencyItem {code:'ISK'; numericCode:'352'; name:qsTr('Iceland Krona'); countries: ['ICELAND']} - CurrencyItem {code:'INR'; numericCode:'356'; name:qsTr('Indian Rupee'); countries: ['INDIA']} - CurrencyItem {code:'IRR'; numericCode:'364'; name:qsTr('Iranian Rial'); countries: ['IRAN']} - CurrencyItem {code:'IQD'; numericCode:'368'; name:qsTr('Iraqi Dinar'); countries: ['IRAQ']} - CurrencyItem {code:'JMD'; numericCode:'388'; name:qsTr('Jamaican Dollar'); countries: ['JAMAICA']} - CurrencyItem {code:'JOD'; numericCode:'400'; name:qsTr('Jordanian Dinar'); countries: ['JORDAN']} - CurrencyItem {code:'KES'; numericCode:'404'; name:qsTr('Kenyan Shilling'); countries: ['KENYA']} - CurrencyItem {code:'PGK'; numericCode:'598'; name:qsTr('Kina'); countries: ['PAPUA NEW GUINEA']} - CurrencyItem {code:'LAK'; numericCode:'418'; name:qsTr('Kip'); countries: ['LAO PEOPLES DEMOCRATIC REPUBLIC']} - //CurrencyItem {code:'EEK'; numericCode:'233'; name:qsTr('Kroon'); countries: ['ESTONIA']} - CurrencyItem {code:'KWD'; numericCode:'414'; name:qsTr('Kuwaiti Dinar'); countries: ['KUWAIT']} - CurrencyItem {code:'ZMK'; numericCode:'894'; name:qsTr('Zambian Kwacha'); countries: ['ZAMBIA']} - CurrencyItem {code:'MWK'; numericCode:'454'; name:qsTr('Malawian Kwacha'); countries: ['MALAWI']} - CurrencyItem {code:'AOA'; numericCode:'973'; name:qsTr('Kwanza'); countries: ['ANGOLA']} - CurrencyItem {code:'MMK'; numericCode:'104'; name:qsTr('Kyat'); countries: ['MYANMAR']} - CurrencyItem {code:'GEL'; numericCode:'981'; name:qsTr('Lari'); countries: ['GEORGIA']} - //CurrencyItem {code:'LVL'; numericCode:'428'; name:qsTr('Latvian Lats'); countries: ['LATVIA']} - CurrencyItem {code:'LBP'; numericCode:'422'; name:qsTr('Lebanese Pound'); countries: ['LEBANON']} - CurrencyItem {code:'ALL'; numericCode:'008'; name:qsTr('Lek'); countries: ['ALBANIA']} - CurrencyItem {code:'HNL'; numericCode:'340'; name:qsTr('Lempira'); countries: ['HONDURAS']} - CurrencyItem {code:'SLL'; numericCode:'694'; name:qsTr('Leone'); countries: ['SIERRA LEONE']} - CurrencyItem {code:'LRD'; numericCode:'430'; name:qsTr('Liberian Dollar'); countries: ['LIBERIA']} - CurrencyItem {code:'SZL'; numericCode:'748'; name:qsTr('Lilangeni'); countries: ['SWAZILAND']} - CurrencyItem {code:'LYD'; numericCode:'434'; name:qsTr('Libyan Dinar'); countries: ['LIBYAN ARAB JAMAHIRIYA']} - // Lithuania uses Euro from 1 January 2015 - //CurrencyItem {code:'LTL'; numericCode:'440'; name:qsTr('Lithuanian Litas'); countries: ['LITHUANIA']} - CurrencyItem {code:'MGA'; numericCode:'969'; name:qsTr('Malagasy Ariary'); countries: ['MADAGASCAR']} - CurrencyItem {code:'MYR'; numericCode:'458'; name:qsTr('Malaysian Ringgit'); countries: ['MALAYSIA']} - CurrencyItem {code:'TMM'; numericCode:'795'; name:qsTr('Manat'); countries: ['TURKMENISTAN']} - CurrencyItem {code:'MUR'; numericCode:'480'; name:qsTr('Mauritius Rupee'); countries: ['MAURITIUS']} - CurrencyItem {code:'MZN'; numericCode:'943'; name:qsTr('Metical'); countries: ['MOZAMBIQUE']} - CurrencyItem {code:'MXN'; numericCode:'484'; name:qsTr('Mexican Peso'); countries: ['MEXICO']} - CurrencyItem {code:'MDL'; numericCode:'498'; name:qsTr('Moldovan Leu'); countries: ['MOLDOVA']} - CurrencyItem {code:'MAD'; numericCode:'504'; name:qsTr('Moroccan Dirham'); countries: ['MOROCCO', 'WESTERN SAHARA']} - CurrencyItem {code:'NGN'; numericCode:'566'; name:qsTr('Naira'); countries: ['NIGERIA']} - CurrencyItem {code:'ERN'; numericCode:'232'; name:qsTr('Nakfa'); countries: ['ERITREA']} - CurrencyItem {code:'NPR'; numericCode:'524'; name:qsTr('Nepalese Rupee'); countries: ['NEPAL']} - CurrencyItem {code:'ANG'; numericCode:'532'; name:qsTr('Netherlands Antillian Guilder'); countries: ['NETHERLANDS ANTILLES']} - CurrencyItem {code:'ILS'; numericCode:'376'; name:qsTr('New Israeli Sheqel'); countries: ['ISRAEL']} - CurrencyItem {code:'RON'; numericCode:'946'; name:qsTr('New Leu'); countries: ['ROMANIA']} - CurrencyItem {code:'NZD'; numericCode:'554'; name:qsTr('New Zealand Dollar'); countries: ['COOK ISLANDS', 'NEW ZEALAND', 'NIUE', 'PITCAIRN', 'TOKELAU']} - CurrencyItem {code:'TWD'; numericCode:'901'; name:qsTr('New Taiwan Dollar'); countries: ['TAIWAN']} - CurrencyItem {code:'TRY'; numericCode:'949'; name:qsTr('Turkish Lira'); countries: ['TURKEY']} - CurrencyItem {code:'KPW'; numericCode:'408'; name:qsTr('North Korean Won'); countries: ['KOREA']} - CurrencyItem {code:'NOK'; numericCode:'578'; name:qsTr('Norwegian Krone'); countries: ['BOUVET ISLAND', 'NORWAY', 'SVALBARD AND JAN MAYEN']} - CurrencyItem {code:'PEN'; numericCode:'604'; name:qsTr('Nuevo Sol'); countries: ['PERU']} - CurrencyItem {code:'MRO'; numericCode:'478'; name:qsTr('Ouguiya'); countries: ['MAURITANIA']} - CurrencyItem {code:'MRU'; numericCode:'929'; name:qsTr('Ouguiya'); countries: ['MAURITANIA']} - CurrencyItem {code:'PKR'; numericCode:'586'; name:qsTr('Pakistan Rupee'); countries: ['PAKISTAN']} - CurrencyItem {code:'XPD'; numericCode:'964'; name:qsTr('Palladium'); countries: []} - CurrencyItem {code:'MOP'; numericCode:'446'; name:qsTr('Pataca'); countries: ['MACAO']} - CurrencyItem {code:'PHP'; numericCode:'608'; name:qsTr('Philippine Peso'); countries: ['PHILIPPINES']} - CurrencyItem {code:'XPT'; numericCode:'962'; name:qsTr('Platinum'); countries: []} - CurrencyItem {code:'GBP'; numericCode:'826'; name:qsTr('Pound Sterling'); symbol: "£"; countries: ['UNITED KINGDOM']} - CurrencyItem {code:'BWP'; numericCode:'072'; name:qsTr('Pula'); countries: ['BOTSWANA']} - CurrencyItem {code:'QAR'; numericCode:'634'; name:qsTr('Qatari Rial'); countries: ['QATAR']} - CurrencyItem {code:'GTQ'; numericCode:'320'; name:qsTr('Quetzal'); countries: ['GUATEMALA']} - CurrencyItem {code:'TOP'; numericCode:'776'; name:qsTr('Paanga'); countries: ['TONGA']} - CurrencyItem {code:'ZAR'; numericCode:'710'; name:qsTr('Rand'); countries: ['SOUTH AFRICA']} - CurrencyItem {code:'OMR'; numericCode:'512'; name:qsTr('Rial Omani'); countries: ['OMAN']} - CurrencyItem {code:'KHR'; numericCode:'116'; name:qsTr('Riel'); countries: ['CAMBODIA']} - CurrencyItem {code:'MVR'; numericCode:'462'; name:qsTr('Rufiyaa'); countries: ['MALDIVES']} - CurrencyItem {code:'IDR'; numericCode:'360'; name:qsTr('Rupiah'); countries: ['INDONESIA']} - CurrencyItem {code:'RUB'; numericCode:'643'; name:qsTr('Russian Ruble'); countries: ['RUSSIAN FEDERATION']} - CurrencyItem {code:'RWF'; numericCode:'646'; name:qsTr('Rwanda Franc'); countries: ['RWANDA']} - CurrencyItem {code:'SHP'; numericCode:'654'; name:qsTr('Saint Helena Pound'); countries: ['SAINT HELENA']} - CurrencyItem {code:'SAR'; numericCode:'682'; name:qsTr('Saudi Riyal'); countries: ['SAUDI ARABIA']} - CurrencyItem {code:'XDR'; numericCode:'960'; name:qsTr('SDR'); countries: ['INTERNATIONAL MONETARY FUND (I.M.F)']} - CurrencyItem {code:'SCR'; numericCode:'690'; name:qsTr('Seychelles Rupee'); countries: ['SEYCHELLES']} - CurrencyItem {code:'RSD'; numericCode:'941'; name:qsTr('Serbian Dinar'); countries: ['SERBIA']} - CurrencyItem {code:'XAG'; numericCode:'961'; name:qsTr('Silver'); countries: []} - CurrencyItem {code:'SGD'; numericCode:'702'; name:qsTr('Singapore Dollar'); countries: ['SINGAPORE']} - //CurrencyItem {code:'SKK'; numericCode:'703'; name:qsTr('Slovak Koruna'); countries: ['SLOVAKIA']} - CurrencyItem {code:'SBD'; numericCode:'090'; name:qsTr('Solomon Islands Dollar'); countries: ['SOLOMON ISLANDS']} - CurrencyItem {code:'TJS'; numericCode:'972'; name:qsTr('Somoni'); countries: ['TAJIKISTAN']} - CurrencyItem {code:'KGS'; numericCode:'417'; name:qsTr('Som'); countries: ['KYRGYZSTAN']} - CurrencyItem {code:'SOS'; numericCode:'706'; name:qsTr('Somali Shilling'); countries: ['SOMALIA']} - CurrencyItem {code:'SSP'; numericCode:'728'; name:qsTr('South Sudanese Pound'); symbol: '£'; countries: ['SOUTH SUDAN']} - CurrencyItem {code:'LKR'; numericCode:'144'; name:qsTr('Sri Lanka Rupee'); countries: ['SRI LANKA']} - CurrencyItem {code:'SDG'; numericCode:'938'; name:qsTr('Sudanese Pound'); countries: ['SUDAN']} - CurrencyItem {code:'SRD'; numericCode:'968'; name:qsTr('Surinam Dollar'); countries: ['SURINAME']} - CurrencyItem {code:'SEK'; numericCode:'752'; name:qsTr('Swedish Krona'); countries: ['SWEDEN']} - CurrencyItem {code:'CHF'; numericCode:'756'; name:qsTr('Swiss Franc'); countries: ['LIECHTENSTEIN']} - CurrencyItem {code:'SYP'; numericCode:'760'; name:qsTr('Syrian Pound'); countries: ['SYRIAN ARAB REPUBLIC']} - CurrencyItem {code:'TND'; numericCode:'788'; name:qsTr('Tunisian Dinar'); countries: ['TUNISIA']} - CurrencyItem {code:'BDT'; numericCode:'050'; name:qsTr('Taka'); countries: ['BANGLADESH']} - CurrencyItem {code:'WST'; numericCode:'882'; name:qsTr('Tala'); countries: ['SAMOA']} - CurrencyItem {code:'TZS'; numericCode:'834'; name:qsTr('Tanzanian Shilling'); countries: ['TANZANIA']} - CurrencyItem {code:'KZT'; numericCode:'398'; name:qsTr('Tenge'); countries: ['KAZAKHSTAN']} - CurrencyItem {code:'TTD'; numericCode:'780'; name:qsTr('Trinidad and Tobago Dollar'); countries: ['TRINIDAD AND TOBAGO']} - CurrencyItem {code:'MNT'; numericCode:'496'; name:qsTr('Tugrik'); countries: ['MONGOLIA']} - CurrencyItem {code:'AED'; numericCode:'784'; name:qsTr('UAE Dirham'); countries: ['UNITED ARAB EMIRATES']} - CurrencyItem {code:'USD'; numericCode:'840'; name:qsTr('US Dollar'); symbol: "$"; countries: ['AMERICAN SAMOA', 'BRITISH INDIAN OCEAN TERRITORY', 'ECUADOR', 'GUAM', 'MARSHALL ISLANDS', 'MICRONESIA', 'NORTHERN MARIANA ISLANDS', 'PALAU', 'PUERTO RICO', 'TIMOR-LESTE', 'TURKS AND CAICOS ISLANDS', 'UNITED STATES MINOR OUTLYING ISLANDS', 'VIRGIN ISLANDS (BRITISH)', 'VIRGIN ISLANDS (U.S.)']} - CurrencyItem {code:'KRW'; numericCode:'410'; name:qsTr('Won'); countries: ['KOREA']} - CurrencyItem {code:'JPY'; numericCode:'392'; name:qsTr('Yen'); countries: ['JAPAN']} - CurrencyItem {code:'CNY'; numericCode:'156'; name:qsTr('Yuan Renminbi'); countries: ['CHINA']} - CurrencyItem {code:'UGX'; numericCode:'800'; name:qsTr('Uganda Shilling'); countries: ['UGANDA']} - CurrencyItem {code:'UZS'; numericCode:'860'; name:qsTr('Uzbekistan Sum'); countries: ['UZBEKISTAN']} - CurrencyItem {code:'VUV'; numericCode:'548'; name:qsTr('Vatu'); countries: ['VANUATU']} - CurrencyItem {code:'YER'; numericCode:'886'; name:qsTr('Yemeni Rial'); countries: ['YEMEN']} - CurrencyItem {code:'ZWD'; numericCode:'716'; name:qsTr('Zimbabwe Dollar'); countries: ['ZIMBABWE']} - CurrencyItem {code:'PLN'; numericCode:'985'; name:qsTr('Zloty'); countries: ['POLAND']} + + function listProperties(obj) { + var propList = ""; + for(var propName in obj) { + if(typeof(obj[propName]) != "undefined") { + console.log('property:', propName, obj[propName]) + } + } + } + + function listElements() { + for(var i = 0; i < rowCount(); i++) { + console.log('Element:', objectName, get(i), typeof get(i)) + } + } + + function update() { + console.log('CurrencyModel.update. children:', typeof this) + var currencies = [] + var currency + var found + var i + + for(i = 0; i < rowCount(); i++) { + var elem = get(i) + var c = {} + c['code'] = elem['code'] + c['name'] = elem['name'] + c['symbol'] = elem['symbol'] + c['num'] = elem['num'] + console.log('currency:', JSON.stringify(c)) + currencies.push(c) + } + //listProperties(get(0)) + //listElements() + var filteredCurrencies = currencies.filter(function (currency) { return currency.name.toLowerCase().indexOf(searchString) !== -1 }) + + // helper objects that can be quickly accessed + var filteredCurrencyObject = new Object + for (i = 0; i < filteredCurrencies.length; ++i) { + filteredCurrencyObject[filteredCurrencies[i]] = true + } + var existingCurrencyObject = new Object + for (i = 0; i < count; ++i) { + currency = get(i).text + existingCurrencyObject[currency] = true + } + + // remove items no longer in filtered set + i = 0 + while (i < count) { + currency = get(i).text + found = filteredCurrencyObject.hasOwnProperty(currency) + if (!found) { + remove(i) + } else { + i++ + } + } + + // add new items + for (i = 0; i < filteredCurrencies.length; ++i) { + currency = filteredCurrencies[i] + found = existingCurrencyObject.hasOwnProperty(currency) + if (!found) { + // for simplicity, just adding to end instead of corresponding position in original list + append(currency) + } + } + } + + Component.onCompleted: { + if(!Currencies.isReady) { + console.log('CurrencyModel. Not ready') + return + } + + var allCurrencies = Currencies.all + var availableCurrencies = Currencies.available + + /*for(var currency in availableCurrencies) { + console.log(currency, availableCurrencies[currency]) + }*/ + + if(Env.isReady) { + // Begin populating + console.log('CurrencyModel. Populating...', availableCurrencies.length) + for(var currency in allCurrencies) { + if (allCurrencies.hasOwnProperty(currency)) { // Of course it has??? + allCurrencies[currency].code = currency + //console.log(currency + " -> " + JSON.stringify(availableCurrencies[currency])); + if(availableCurrencies[currency]) { + //console.log(currency + " -> " + JSON.stringify(availableCurrencies[currency])); + append(allCurrencies[currency]) + }/* else { + console.log('Could not find:', currency, + ' in ', JSON.stringify(availableCurrencies[currency])) + }*/ + } + } + } else { + console.error('One or both variables "allCurrencies" and "availableCurrencies" are empty.') + } + } } diff --git a/qml/components/CurrencyItem.qml b/qml/components/CurrencyPair.qml similarity index 77% rename from qml/components/CurrencyItem.qml rename to qml/components/CurrencyPair.qml index c083ef7..561f36b 100644 --- a/qml/components/CurrencyItem.qml +++ b/qml/components/CurrencyPair.qml @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2018 Thomas Tanghus + Copyright (C) 2019 Thomas Tanghus All rights reserved. You may use this file under the terms of BSD license as follows: @@ -28,18 +28,23 @@ */ import QtQuick 2.6 -import Sailfish.Silica 1.0 -MenuItem { - property string code: ''; - property string numericCode: ''; - property string name: ''; - property string symbol: ''; - property variant countries: []; +QtObject { + readonly property string objectType: 'CurrencyPair' + objectName: from + '/' + to + '=' + rate + property string from: '' + property string to: '' + property double rate: 0.0 + property string date: '' - text: name + ' (' + (symbol || code) + ')'; + function init(dict) { + from = dict.from + to = dict.to + rate = dict.rate + date = dict.date + } - function getSymbol() { - return symbol || code; + function toString() { + return objectName } } diff --git a/qml/components/Env.qml b/qml/components/Env.qml new file mode 100644 index 0000000..84d7724 --- /dev/null +++ b/qml/components/Env.qml @@ -0,0 +1,60 @@ +/* + Copyright (C) 2019 Thomas Tanghus + All rights reserved. + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +pragma Singleton + +import QtQuick 2.6 +import '.' + +QtObject { + property bool _isBusy: false + readonly property bool isReady: Currencies.isReady + readonly property bool isOnline: network.isOnline || false // network.isOnline ? network.isOnline : false + readonly property bool isBusy: (_isBusy || !Currencies.isReady) + //onIsOnlineChanged: console.log('Env.isOnline:', isOnline) + //onIsReadyChanged: console.log('Env.isReady:', isReady) + onIsBusyChanged: console.log('Env.isBusy:', isBusy) + + // This is for setting before requesting a result and when it's recieved. + // This stops request and other actions, blocks for user input and shows busy indicator. + function setBusy(state) { + //console.log('Setting busy:', state) + _isBusy = state + } + + property var network: { + var component = Qt.createComponent(Qt.resolvedUrl('Network.qml')); + if (component.status === Component.Error) { + console.error(component.errorString()); + return 0; + } + + return component.createObject(); + } +} diff --git a/qml/components/ExchangeProvider.qml b/qml/components/ExchangeProvider.qml index 9f8deb9..5dc212e 100644 --- a/qml/components/ExchangeProvider.qml +++ b/qml/components/ExchangeProvider.qml @@ -28,27 +28,199 @@ */ import QtQuick 2.6 -// NOTE: QtObject { ? +import "." + Item { id: provider - property string url: '' + property string name: 'Generic Exchange Rate Provider' + property string rateURL: '' + property string availableURL: '' + property string url: rateURL // Holds the Storage component. property var cache - // The update interval the provider supports in minutes - property int updateInterval: 1440 + // The update interval the provider supports in minutes. + // www.exchangerate-api.com - daily + // api.openrates.io (similar to fixer.io free) + // For currencystack.io it's hourly or 10 minutes. + // For exchangeratesapi.com it's daily. + // For Fixer.io/currencylayer.com it's daily, hourly, 10 minutes, 60 seconds. + property int updateInterval: 24*60*60 // 24 hours. + property var updateWeekdays: [0,1,2,3,4,5,6] property date _lastUpdated: new Date() - signal rateRecieved(string from, string to, string rate) - signal error() + signal rateRecieved(var pair) + signal availableRecieved(var availableCurrencies) + signal error(string error, string message) + + Requester { + id: rateFetcher + url: provider.url + onMessage: { + // This handler receives responses from request on either + // one rate, e.g. EUR/USD, or for all available currencies + // from the current provider. It uses the 'requestType' + // argument to determine how to parse the response + // The results are either from the cache or online + // TODO: This method should really be split up. + //console.log('ExchangeProvider.rateFetcher.onMessage:', JSON.stringify(messageObject).substring(0, 50)) + if(messageObject.request && messageObject.response ) { + if(messageObject.request.args.requestType) { + var _data + if(messageObject.request.args.requestType === 'rate') { + // 'parseRateResponse' must be implemented by subclasses. + _data = provider.parseRateResponse( + messageObject.request, + messageObject.response) + console.log('ExchangeProvider.rateFetcher.onMessage:', JSON.stringify(_data)) + cache.setRate(_data.from, _data.to, _data.rate, _data.date) + // Signal received + provider.rateRecieved(Currencies.createPair(_data)) + } else if(messageObject.request.args.requestType === 'available') { + // Signal received + provider.availableRecieved(messageObject.response) + console.log('ExchangeProvider.rateFetcher. available:', messageObject.length, + JSON.stringify(messageObject.response).substring(0, 100)) + // 'parseAvailableResponse' must be implemented by subclasses. + _data = provider.parseAvailableResponse( + messageObject.request, + messageObject.response) + for(var currency in _data) { + console.log('rateFetcher.cache.setRate:', JSON.stringify(_data[currency])) + cache.setRate(_data[currency].from, _data[currency].to, + _data[currency].rate, _data[currency].date) + } + } else { + var str = qsTr('No "requestType" set in request. Use "rate" or "available"') + console.error(str) + throw new Error(qsTr('Error'), str) + } + } + } else { + provider.error(messageObject.error, messageObject.message) + console.warn(messageObject.error, messageObject.message) + } + } + } + + // Fetch a list of available currencies either from cache or from + // the current provider. + function getAvailable(base, force) { + var response, doUpdate = false // NOTE: Set to false in production. + + rateFetcher.url = availableURL + + // Try to get it from the cache + if(force) { + doUpdate = true + } else { + cache.getAvailable(base, function(response) { + if(response.length > 0) { + var rates = {} + for(var i = 0; i < response.length; i++) { + var code = response[i].code + rates[code] = parseFloat(response[i].rate) + //console.log('ExchangeProvider.getAvailable. rate:', code, + //JSON.stringify(rates[code])) + } + console.log('ExchangeProvider.getAvailable. rates:', JSON.stringify(rates)) + console.log('ExchangeProvider.getAvailable. Fetching "' + base + '" OFFLINE') + doUpdate = false + // Signal received + provider.availableRecieved(rates) + } else { + doUpdate = true + } + }) + } + + if(doUpdate) { + if(Env.isOnline && !workOffline) { + console.log('ExchangeProvider.getAvailable. Fetching "' + base + '" ONLINE') + rateFetcher.request( {'from': fromCode, 'requestType': 'available'} ) + } else { + // TODO: Notify that the user has to get online + console.log('ExchangeProvider.getAvailable() NOT ONLINE!!') + } + } + + } + + function getRate(fromCode, toCode) { + // FIXME: Using global var 'workOffline' :/ + var response, doUpdate = false + + rateFetcher.url = rateURL + console.log('ExchangeProvider.getRate(', fromCode, toCode, ')') + // Try to get it from the cache + // TODO: The cache validation needs cleanup if possible. + cache.getRate(fromCode, toCode, function(response) { + console.log('ExchangeProvider.getRate()', JSON.stringify(response)) + if(response && response.rate) { + var now, then + + now = new Date() + then = new Date(response['date']) + + // Is it older than a updateInterval'? + console.log('getRate:', + Math.round(now.getTime()/1000), '-', + Math.round(then.getTime()/1000), '>', updateInterval) + if(now.getTime() - then.getTime() > updateInterval*1000) { + console.log('getRate: expired. Weekday?', JSON.stringify(updateWeekdays), now.getDay()) + if (updateWeekdays.indexOf(now.getDay()) !== -1) { + // NOTE: workOffline shouldn't be used here + doUpdate = workOffline ? false : true + console.log('getRate: weekday. workOffline?', workOffline, 'Update?', doUpdate) + } else { + console.log('Not weekday. Update?', doUpdate) + } + } else { + console.log('getRate(). Not expired') + } + + if(!doUpdate) { + console.log('ExchangeProvider.getRate. OFFLINE response:', response.rate) + // The response is OK. Format it to fit with the required format + var pair = Currencies.createPair(response) + // Signal received + // is caught in App.onRateRecieved + provider.rateRecieved(pair) + } + } else { + console.log('ExchangeProvider.getRate(). Nothing cached') + // Nothing cached + doUpdate = true + } + + // NOTE: workOffline shouldn't be here + if(doUpdate) { + if(Env.isOnline && !workOffline) { + rateFetcher.request( {'from': fromCode, 'to': toCode, 'requestType': 'rate'} ) + } else if(doUpdate) { + var str = qsTr("You have chosen to work offline, but the currency combination \ + %1 => %2 is not in the cache.").arg(fromCode).arg(toCode); + provider.error(qsTr('Error'), str) + + //pageStack.push(Qt.resolvedUrl('pages/SettingsDialog.qml'), {info: str}) + } + } + }) + } - function getRate() { + // Parse response from rateFetcher and return an object: {from, to, rate, date} + // This MUST be implemented by subclasses + function parseRateResponse(request, response) { // This should never get called + console.error('ExchangeProvider.parseRateResponse. This should never get called!') + throw new Error(qsTr('ExchangeProvider.parseRateResponse. Must be implemented by subclass')) } - // Parse response from rateFetcher and return an object: - // {from, to, rate, date} - function parseResponse(request, response) { + // Parse response from rateFetcher and return an object: {from, to, rate, date} + // This MUST be implemented by subclasses + function parseAvailableResponse(request, response) { // This should never get called + console.error('ExchangeProvider.parseAvailableResponse. This should never get called!') + throw new Error(qsTr('ExchangeProvider.parseAvailableResponse. Must be implemented by subclass')) } } diff --git a/qml/components/ExchangeRatesAPIProvider.qml b/qml/components/ExchangeRatesAPIProvider.qml index c3907fe..91bc81d 100644 --- a/qml/components/ExchangeRatesAPIProvider.qml +++ b/qml/components/ExchangeRatesAPIProvider.qml @@ -31,100 +31,48 @@ import QtQuick 2.6 ExchangeProvider { id: provider - updateInterval: 36*60*60 // 36 hours + property string name: 'ExchangeRatesAPI.io' + updateInterval: 24*60*60 // 24 hours. For Fixer.io it's 60 seconds. // Monday thru Friday updateWeekdays: [1,2,3,4,5] // The rates are only updated on week days. - url: 'https://api.exchangeratesapi.io/latest?base={from}&symbols={to}' - - // TODO: Move this to ExchangeProvider when properly tested - Requester { - id: rateFetcher - url: parent.url - onMessage: { - console.log('rateFetcher.onMessage:', JSON.stringify(messageObject)) - console.log('rateFetcher.onMessage. response:', JSON.stringify(messageObject.response)) - if(messageObject.request && messageObject.response ) { - var _data = provider.parseResponse(messageObject.request, messageObject.response) - cache.setRate(_data.from, _data.to, _data.rate, _data.date) - provider.rateRecieved(_data.from, _data.to, _data.rate) - } else { - provider.error(messageObject.error, messageObject.message) - console.warn(messageObject.error, messageObject.message) - } - } - } + rateURL: 'https://api.exchangeratesapi.io/latest?requestType=rate&base={from}&symbols={to}' + availableURL: 'https://api.exchangeratesapi.io/latest?requestType=available&base={from}&symbols' // Parse response from rateFetcher and return an object: - // {rate, date} - function parseResponse(request, response) { + // {from, to, rate, date} + function parseRateResponse(request, response) { var _f = request.args.from var _t = request.args.to var _r = parseFloat(response.rates[_t]) + // Fixer.io also has a 'timestamp' value. var _d = response.date ? response.date : _lastUpdated.toISOString() return {from: _f, to: _t, rate: _r, date: _d} } - // TODO: Probably move this to ExchangeProvider when properly tested - function getRate() { - // Using global vars 'isOnline' and 'workOffline' :/ - var response, doUpdate = false - - // Try to get it from the cache - // NOTE: Maybe the Storage cache should be instantiated in ExchangeProvider? - cache.getRate(fromCode, toCode, function(response) { - //console.log('App.getRate()', response) - if(response.rate) { - //console.log('App.getRate(). rate:', response.rate) - var now, then - - now = new Date() - then = new Date(response['date']) - - // Is it older than a updateInterval?' - if(now.getTime() - then.getTime() > updateInterval*1000) { - //if(updateWeekdays.includes(now.getDay())) { - if (updateWeekdays.indexOf(now.getDay()) != -1) { - console.log("It's a WEEKDAY") - // NOTE: workOffline shouldn't be here - doUpdate = workOffline ? false : true - } else { - console.log("It's WEEKEND") - } - } - if(!doUpdate) { - provider.rateRecieved( - fromCode, - toCode, - parseFloat(response['rate']) - ) - } - } else { - console.log('App.getRate(). Nothing cached') - // Nothing cached - doUpdate = true - } - - // NOTE: isOnline and workOffline shouldn't be here - if(doUpdate && !workOffline) { - if(isOnline) { - rateFetcher.request( {'from': fromCode, 'to': toCode} ) - } else { - console.log('Network is down') - provider.error(qsTr('Error'), qsTr('Network is down')) - } - } else if(doUpdate) { - var str = qsTr("You have chosen to work offline, but the currency combination \ - %1 => %2 is not in the cache.").arg(fromCode).arg(toCode); - provider.error(qsTr('Error'), str) - - //pageStack.push(Qt.resolvedUrl('pages/SettingsDialog.qml'), {info: str}) + /* Parse response to initial request for available currencies. + Return as an object: + { + "CAD":{"date":"2019-09-03","from":"EUR","to":"CAD"}, + "HKD":{"date":"2019-09-03","from":"EUR","to":"HKD"}, + "PHP":{"date":"2019-09-03","from":"EUR","to":"PHP"}, + And so forth.... + } + */ + function parseAvailableResponse(request, response) { + var date = response.date + var base = response.base + var rates = {} + console.log('ExchangeRatesAPIProvide.parseAvailableResponse:', JSON.stringify(response)) + for(var currency in response.rates) { + rates[currency] = { + from: base, + to: currency, + date: date, + rate: response.rates[currency] } - }) - - // NOTE: This should be set in app after rateRecieved() signal, not here - settings.fromCode = fromCode - settings.toCode = toCode - settings.multiplier = multiplier + console.log('parseAvailableResponse:', currency, JSON.stringify(rates[currency])) + } + return rates } } diff --git a/qml/components/JSONListModel.qml b/qml/components/JSONListModel.qml deleted file mode 100644 index c1eaae7..0000000 --- a/qml/components/JSONListModel.qml +++ /dev/null @@ -1,56 +0,0 @@ -/* JSONListModel - a QML ListModel with JSON and JSONPath support - * - * Copyright (c) 2012 Romain Pokrzywka (KDAB) (romain@kdab.com) - * Licensed under the MIT licence (http://opensource.org/licenses/mit-license.php) - * From: https://github.com/kromain/qml-utils/tree/master/JSONListModel - */ - -import QtQuick 2.6 -import "./jsonpath.js" as JSONPath - -Item { - property string source: "" - property string json: "" - property string query: "" - - property ListModel model : ListModel { id: jsonModel } - property alias count: jsonModel.count - - onSourceChanged: { - console.log('JSONListModel. Opening:', source) - var xhr = new XMLHttpRequest; - xhr.open("GET", source); - xhr.onreadystatechange = function() { - if (xhr.readyState === XMLHttpRequest.DONE) { - console.log('xhr.status:', xhr.status, xhr.statusText) - json = xhr.responseText; - } - } - xhr.send(); - } - - Component.onCompleted: { - console.log('JSONListModel.onCompleted. count:', count) - } - - onJsonChanged: { - updateJSONModel() - } - - onQueryChanged: updateJSONModel() - - function updateJSONModel() { - jsonModel.clear(); - - if ( json === "" ) - return; - - var objectArray = JSON.parse(json).rates; - for ( var key in objectArray ) { - var jo = objectArray[key]; - - jsonModel.append( { "code": key, "rate": jo } ); - } - } - -} diff --git a/qml/components/Network.qml b/qml/components/Network.qml new file mode 100644 index 0000000..c9b23dd --- /dev/null +++ b/qml/components/Network.qml @@ -0,0 +1,48 @@ +/* + Copyright (C) 2019 Thomas Tanghus + All rights reserved. + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +import QtQuick 2.6 +import org.freedesktop.contextkit 1.0 +import Nemo.DBus 2.0 + +QtObject { + id: network + property bool isOnline: state.value === 'connected' + property ContextProperty state + + onIsOnlineChanged: console.log('Env.Network.isOnline:', isOnline) + + state: ContextProperty { + // `cat /run/state/namespaces/Internet/NetworkState` + id: networkOnline + key: 'Internet.NetworkState' + /*onValueChanged: { + console.log('Env.Network.state', value, isOnline) + }*/ + } +} diff --git a/qml/components/Requester.qml b/qml/components/Requester.qml index 2d5c1d6..9f6d3b0 100644 --- a/qml/components/Requester.qml +++ b/qml/components/Requester.qml @@ -30,12 +30,19 @@ import QtQuick 2.6 WorkerScript { - id: rateFetcher + id: requester source: Qt.resolvedUrl('requester.mjs') property string url: '' function request(args) { - console.log('rateFetcher.request:', JSON.stringify(args)) + //console.log('Requester.request:', JSON.stringify(args)) sendMessage({url: url, args: args}) } + + Component.onCompleted: { + if(url === '') { + console.trace() + throw new Error('Requester: ' + qsTr('"URL" must be set by subclasses')) + } + } } diff --git a/qml/components/Settings.qml b/qml/components/Settings.qml index f89015a..b3de520 100644 --- a/qml/components/Settings.qml +++ b/qml/components/Settings.qml @@ -1,4 +1,32 @@ -import QtQuick 2.0 +/* + Copyright (C) 2019 Thomas Tanghus + All rights reserved. + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +import QtQuick 2.6 import Nemo.Configuration 1.0 ConfigurationGroup { @@ -6,21 +34,25 @@ ConfigurationGroup { path: "/apps/harbour-currencyconverter" - property string fromCode - property string toCode + // Use 'version' to compare after updates, + // if DB, settings or other needs updates. + property string version: '0.1' + property bool firstRun: true + property string fromCode: 'EUR' + property string toCode: 'USD' // Usually the same as above, but can be e.g. £ or $ - property string fromSymbol - property string toSymbol + //property string fromSymbol + //property string toSymbol // The amount to multiply the rate with - property double multiplier + property double multiplier: 1 // The number of decimals to show the result with - property int numDecimals + property int numDecimals: 2 // The last result before multiplication property double rate: 1.0 - property bool workOffline: true + property bool workOffline: false } diff --git a/qml/components/Storage.qml b/qml/components/Storage.qml index 7e0b052..8c00e28 100644 --- a/qml/components/Storage.qml +++ b/qml/components/Storage.qml @@ -32,6 +32,7 @@ import QtQuick.LocalStorage 2.0 as LS QtObject { property string dbName: '' + // TODO: Change this to 'property var tables: [] property string tblName: '' property string dbDescription: dbName; // TODO: Check what database version means @@ -49,7 +50,9 @@ QtObject { _hasTable = _getTable() } + // TODO: Use callback method if provided function _formatException(e) { + console.error(e) console.trace() throw e } @@ -60,7 +63,7 @@ QtObject { } if(!typeof dbName === 'string' || !dbName.trim()) { - _formatException(new Error(qsTr('No table name has been set'))) + _formatException(new Error(qsTr('No database name has been set'))) } try { @@ -108,6 +111,7 @@ QtObject { } sql += ')' + console.log('Storage._getTable. SQL:', sql) try { _dbObj.transaction( function(tx) { @@ -129,7 +133,7 @@ QtObject { * @return undefined or throws exception */ function set(fields, values) { - _getTable() + //_getTable() if(fields.length !== values.length) { _formatException( new Error(qsTr('The number of values must match the number of fields'))) @@ -145,20 +149,11 @@ QtObject { + '(' + fieldsString + ')' + ' VALUES ("' + valuesString + '");' console.log('Storage.set() SQL:', sql); - - try { - _dbObj.transaction( - function(tx) { - tx.executeSql(sql) - } - ) - } catch(e) { - _formatException(e) - } + executeSQL(sql) } function get(fields, where, cb) { - _getTable() + //_getTable() var whereList = [], sql = 'SELECT ' @@ -175,56 +170,65 @@ QtObject { sql += ' FROM '+ tblName +' WHERE ' for(var w in where) { if (where.hasOwnProperty(w)) { - console.log(w + " -> " + where[w]); + //console.log(w + " -> " + where[w]); whereList.push(w + '="' + where[w] + '"') } } sql += whereList.join(' AND ') console.log('Storage.get() SQL:', sql) - try { - _dbObj.transaction( - function(tx) { - tx.executeSql(sql) - var result = tx.executeSql(sql); + executeSQL(sql, cb) + } - if (result.rows.length > 0) { - var row = result.rows.item(0); - cb(row); - } else { - // TODO: callback should contain result or error msg(?) - cb(false); - } - } - ) - } catch(e) { - _formatException(e) - } + function remove(where, cb) { + _getTable() + var whereList = [], sql = 'DELETE FROM ' + tblName + + // The WHERE clauses + sql += ' WHERE ' + for(var w in where) { + if (where.hasOwnProperty(w)) { + //console.log(w + " -> " + where[w]); + whereList.push(w + '="' + where[w] + '"') + } + } + sql += whereList.join(' AND ') + console.log('Storage.remove() SQL:', sql) + executeSQL(sql, cb) } function truncate(cb) { _getTable() var sql = 'DELETE FROM ' + tblName + console.log('Storage.truncate. SQL:', sql) + + executeSQL(sql, cb) + } + + function executeSQL(sql, cb) { + console.log('Storage.executeSQL:', sql) + _getTable() try { _dbObj.transaction( function(tx) { - tx.executeSql(sql) var result = tx.executeSql(sql); - if (result.rows.length > 0) { - var row = result.rows.item(0); - cb(true); - } else { - // TODO: callback should contain result or error msg(?) - cb(false); + //console.log('Storage.getFromSQL:', JSON.stringify(result.rows)) + console.log('Storage.executeSQL. rows.length:', result.rows.length) + var rows = [] + for (var i = 0; i < result.rows.length; i++) { + rows.push(result.rows.item(i)) + //console.log(JSON.stringify(rows[i])) + } + if(cb) { + cb(rows); } } ) } catch(e) { _formatException(e) } - } } diff --git a/qml/components/qmldir b/qml/components/qmldir new file mode 100644 index 0000000..66bf29e --- /dev/null +++ b/qml/components/qmldir @@ -0,0 +1,4 @@ +module harbour.currencyconverter.environment +singleton Env 0.1 Env.qml +singleton Currencies 0.1 Currencies.qml + diff --git a/qml/components/requester.mjs b/qml/components/requester.mjs index 4f77f6b..b2fbd7b 100644 --- a/qml/components/requester.mjs +++ b/qml/components/requester.mjs @@ -1,5 +1,5 @@ /* -Copyright (c) 2013-2019 Thomas Tanghus +Copyright (c) 2019 Thomas Tanghus You may use this file under the terms of BSD license as follows: @@ -26,31 +26,31 @@ Copyright (c) 2013-2019 Thomas Tanghus SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ //import "utils.js" as Utils -/* - Get all currencies ('.length' is parts of the array) - https://api.exchangeratesapi.io/latest?base=DKK&symbols= - Object.keys(r.rates); - Add an extra argument to messages object, to treat it accordingly -*/ + WorkerScript.onMessage = function(message) { var url = message.url.supplant(message.args) - console.log('message', JSON.stringify(message)) - console.log('url', url) + console.log('Requester.onMessage', JSON.stringify(message)) + console.log('Requester.onMessage. url:', url) var xhr = new XMLHttpRequest(); xhr.timeout = 3000; xhr.onreadystatechange = function() { if (xhr.readyState === XMLHttpRequest.DONE) { - console.log('requester: status:', xhr.status, xhr.statusText) if(xhr.status >= 200 && xhr.status < 300) { + console.log('requester: status/size:', xhr.status, xhr.statusText, xhr.responseText.length) var result = JSON.parse(xhr.responseText); WorkerScript.sendMessage({response: result, request: message}); } else { console.log('requester.js', xhr.statusText, JSON.parse(xhr.responseText).error); - WorkerScript.sendMessage({error: xhr.statusText, message: JSON.parse(xhr.responseText).error}); + WorkerScript.sendMessage({ + error: xhr.statusText, + message: JSON.parse(xhr.responseText).error, + request: message + } + ); } } } @@ -63,6 +63,7 @@ WorkerScript.onMessage = function(message) { xhr.send(); } + String.prototype.supplant = function (o) { try { return this.replace(/{([^{}]*)}/g, @@ -76,3 +77,4 @@ String.prototype.supplant = function (o) { } }; + diff --git a/qml/components/utils.js b/qml/components/utils.js index 8517b9a..e47e2ab 100644 --- a/qml/components/utils.js +++ b/qml/components/utils.js @@ -1,3 +1,32 @@ +/* +Copyright (c) 2019 Thomas Tanghus + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +.pragma library +/* function interpolate(str, o) { try { return str.replace(/{([^{}]*)}/g, @@ -10,3 +39,16 @@ function interpolate(str, o) { console.log('Oops') } }; +*/ +String.prototype.interpolate = function (o) { + try { + return this.replace(/{([^{}]*)}/g, + function (a, b) { + var r = o[b]; + return typeof r === 'string' || typeof r === 'number' ? r : a; + } + ); + } catch(e) { + + } +}; diff --git a/qml/cover/CoverPage.qml b/qml/cover/CoverPage.qml index d846b1d..37223b8 100644 --- a/qml/cover/CoverPage.qml +++ b/qml/cover/CoverPage.qml @@ -29,6 +29,7 @@ import QtQuick 2.6 import Sailfish.Silica 1.0 +import '../components' CoverBackground { @@ -38,7 +39,7 @@ CoverBackground { id: busyIndicator anchors.centerIn: parent size: BusyIndicatorSize.Large - running: isBusy && active + running: Env.isBusy } Column { @@ -52,7 +53,7 @@ CoverBackground { text: qsTr('Currency') font { bold: true - family: Theme.fontFamilyHeading + family: Theme.fontFamily pixelSize: Theme.fontSizeLarge } width: parent.width @@ -62,14 +63,14 @@ CoverBackground { Label { text: qsTr('Converter') font.bold: true - font.family: Theme.fontFamilyHeading + font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeLarge width: parent.width truncationMode: TruncationMode.Fade horizontalAlignment: Text.AlignHCenter } Label { - text: fromSymbol + ' ' + multiplier + text: app.fromCode + ' ' + app.multiplier font.pixelSize: Theme.fontSizeLarge horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignBottom @@ -82,7 +83,7 @@ CoverBackground { width: parent.width } Label { - text: toSymbol + ' ' + qsTr("%L1").arg(result) + text: app.toCode + ' ' + qsTr("%L1").arg(app.result) font.pixelSize: Theme.fontSizeLarge horizontalAlignment: Text.AlignHCenter width: parent.width @@ -94,7 +95,20 @@ CoverBackground { CoverAction { iconSource: "image://theme/icon-cover-refresh" - onTriggered: getRate() + onTriggered: { + if(!Env.isBusy) { + getRate() + } + } + } + CoverAction { + iconSource: "image://theme/icon-cover-transfers" + onTriggered: { + console.log('TODO: Cover. Switching') + //if(!Env.isBusy) { + // getRate() + //} + } } } } diff --git a/qml/harbour-currencyconverter.qml b/qml/harbour-currencyconverter.qml index ef1ad5e..c3c344a 100644 --- a/qml/harbour-currencyconverter.qml +++ b/qml/harbour-currencyconverter.qml @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2018 Thomas Tanghus + Copyright (C) 2013-2019 Thomas Tanghus All rights reserved. You may use this file under the terms of BSD license as follows: @@ -31,6 +31,7 @@ import QtQuick 2.6 import Sailfish.Silica 1.0 import org.freedesktop.contextkit 1.0 import Nemo.DBus 2.0 +//import harbour.currencyconverter.environment 0.1 //import harbour.currencyconverter.fileproxy 1.0 import "cover" import "pages" @@ -41,6 +42,17 @@ ApplicationWindow { id: app + // A Currency Pair is the combination of two currencies and their current + // exchange rate. A Currency pair can be e.g. EUR/USD, where in this case + // USD is the Base Currency. + // In this context a pair is an object with the properties: + // 'from', 'to', 'rate', and 'date' + // where 'from' is the three-letter Base Currency, and 'to' is + // the Minor Currency. 'rate' is of course the exchange rate, and 'date' + // is the date(time) the service reports the rate has changed. + + property var currentPair + // E.g. USD, EUR, DKK property string fromCode property string toCode @@ -56,36 +68,104 @@ ApplicationWindow { property int numDecimals // The last result before multiplication - // NOTE: Changed from string. property double rate: 1.0 // The multiplied result // The reason for having two variables, is to avoid double multiplication property double tmpResult: 1.0 property double result: 1.0 + property string dateRecieved: '' - property bool isBusy: true property bool workOffline: false - property bool isOnline: false - // An object containing all current currencies - property variant currencies + property bool isOnline: Env.isOnline + property var allCurrencies: Currencies.all + property var availableCurrencies: Currencies.available property string locale: Qt.locale().name + // https://doc.qt.io/qt-5/qtqml-syntax-objectattributes.html#object-list-property-attributes + // https://doc.qt.io/qt-5/qml-list.html + //property list providers + // The final result: amount * rate - onTmpResultChanged: result = Number(tmpResult * multiplier).toFixed(numDecimals) - onNumDecimalsChanged: result = Number(tmpResult * multiplier).toFixed(numDecimals) + onTmpResultChanged: updateResult('tmpResult', tmpResult) + onNumDecimalsChanged: updateResult('numDecimals', numDecimals) + onMultiplierChanged: updateResult('multiplier', multiplier) + + function updateResult(field, value) { + // This triggers an update in frontPage + result = Number(tmpResult * multiplier).toFixed(numDecimals) + } + onLocaleChanged: { - console.log('App.onLocaleChanged:', locale) + //console.log('App.onLocaleChanged:', locale) if(!locale || locale === 'C') { locale = 'en_GB' } } + onCurrentPairChanged: { + console.log('App.currentPair:', JSON.stringify(currentPair)) + } + + Timer { + id: kickOff + interval: 300; running: true; repeat: true + onTriggered: { + if(Currencies.isReady) { + console.log('KICKOFF!!!!!!!') + stop() + repeat = false + if(!Env.isOnline && !workOffline) { + networkIFace.openConnection() + } + getRate() + } else { + restart() + } + } + } + + onIsOnlineChanged: { + fromCode = settings.value('fromCode', 'USD') + toCode = settings.value('toCode', 'EUR') + multiplier = settings.value('multiplier', 1) + numDecimals = settings.value('numDecimals', 2) + rate = settings.value('rate', 1.0) + workOffline = settings.value('workOffline', false) + console.log('App.isOnline:', Env.isOnline) //, fromCode, '=>', toCode) + + if(settings.firstRun) { + // TODO: Use for first time loaded + // Use a 'Loader' to load a 'Requester' to execute DB schema(s). + // When DB is created, signal to Currencies/Env. + } + + allCurrenciesFetcher.request({}) + provider.getAvailable(toCode) + //storage.getAvailable(fromCode) + //storage.getRaw('SELECT * FROM rates WHERE fromCode="CZK"') + // Start timer to monitor when Currencies data is ready. + kickOff.start() + } + + Binding { + target: app + property: 'isOnline' + value: Env.isOnline + } + + Binding { + target: app + property: 'allCurrencies' + value: Currencies.all + } + allowedOrientations: Orientation.Portrait | Orientation.Landscape //defaultAllowedOrientations initialPage: Component { - id: frontPage; - FrontPage {} + FrontPage { + id: frontPage; + } } /* @@ -100,6 +180,9 @@ ApplicationWindow { Settings { id: settings + Component.onCompleted: { + // TODO: Check if 'version' matches current version. + } } /*FileProxy { @@ -116,17 +199,8 @@ ApplicationWindow { } }*/ - ContextProperty { - // `cat /run/state/namespaces/Internet/NetworkState` - id: networkOnline - key: 'Internet.NetworkState' - onValueChanged: { - isOnline = value === 'connected' ? true : false - console.log('Connected', isOnline) - } - } - // Popup the network selection dialogue + // Maybe move this to Env.network? DBusInterface { id: networkIFace service: 'com.jolla.lipstick.ConnectionSelector' @@ -134,8 +208,6 @@ ApplicationWindow { iface: 'com.jolla.lipstick.ConnectionSelectorIf' function openConnection() { - console.log('DBusInterface.openConnection') - console.trace() call('openConnectionNow', 'wifi') } } @@ -150,58 +222,26 @@ ApplicationWindow { id: busyIndicator anchors.centerIn: parent size: BusyIndicatorSize.Large - running: isBusy - } - - Storage { - id: storage - // TODO: This creates some weird path. - dbName: StandardPaths.data - tblName: 'rates' - // Use Map? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map - columns: ({ - fromCurrency: 'TEXT', - toCurrency: 'TEXT', - rate: 'TEXT', - date: 'TEXT' - }) - key: ['fromCurrency', 'toCurrency'] - - function setRate(fromCurrency, toCurrency, rate, date) { - try { - set(['fromCurrency', 'toCurrency', 'rate', 'date'], - [fromCurrency, toCurrency, rate, date]) - } catch(e) { - console.error(e) - } - } - - function getRate(from, to, cb) { - try { - get(['rate'], {'fromCurrency': fromCode, 'toCurrency': toCode}, - function(row) {cb(row)}) - } catch(e) { - console.log(e) - } - } - - function getAll(from, cb) { - try { - get(['rate'], {'fromCurrency': fromCode, 'toCurrency': ''}, - function(row) {cb(row)}) - } catch(e) { - console.log(e) - } - } + running: Env.isBusy + //onRunningChanged: console.log('busyIndicator.running', busyIndicator.running) } + // TODO: Move 'storage' to separate file 'Cache.qml' // Used for instantiating object with all currencies. Requester { - id: currenciesFetcher - url: Qt.resolvedUrl('../data/currencies_{locale}.json'.replace('{locale}', locale)) + id: allCurrenciesFetcher + url: Qt.resolvedUrl('../data/currencies.json') + //url: Qt.resolvedUrl('../data/currencies_{locale}.json'.replace('{locale}', locale)) onMessage: { - console.log('currenciesFetcher.onMessage:') //, JSON.stringify(messageObject)) - currencies = messageObject.response + console.log('allCurrenciesFetcher.onMessage:', JSON.stringify(messageObject).substring(0, 200)) + var all = messageObject.response + for(var currency in all) { + // 'code' is the key, but not in the object itself. + all[currency]['code'] = currency + //console.log('currency:', JSON.stringify(all[currency]['code'])) + } + + Currencies.all = all } } @@ -211,108 +251,68 @@ ApplicationWindow { source: 'ExchangeProviderXXX' } */ - Requester { - id: rateFetcher + + Cache { + id: storage + } + + ExchangeRatesAPIProvider { + id: provider url: 'https://api.exchangeratesapi.io/latest?base={from}&symbols={to}' - onMessage: { - console.log('rateFetcher.onMessage:', JSON.stringify(messageObject)) - console.log('rateFetcher.onMessage. response:', JSON.stringify(messageObject.response)) - if(messageObject.request && messageObject.response ) { - // TODO: This part needs to be generalized - var _f = messageObject.request.args.from - var _t = messageObject.request.args.to - var _r = messageObject.response.rates[_t] - var _d = messageObject.response.date - tmpResult = parseFloat(_r) - storage.setRate(_f, _t, _r, _d) - } else { - notifier.notify(messageObject.error, messageObject.message) - console.warn(messageObject.error, messageObject.message) + cache: storage + + // The signal is sent from ExchangeProvider.getRate() + onRateRecieved: { + // This triggers frontPage.onCurrentPairChanged + if(!pair) { + console.error('App.provider.onRateRecieved: Got empty pair!') + console.trace() + Env.setBusy(false) + return } - setBusy(false) + currentPair = pair + // This is recieved in onTmpResultChanged where it is formatted and assigned to 'result' + tmpResult = parseFloat(pair.rate) + dateRecieved = pair.date + Env.setBusy(false) } - } + onAvailableRecieved: { + console.log('App.provider.onAvailableRecieved:', JSON.stringify(availableCurrencies)) - Component.onCompleted: { - setBusy(true) - fromCode = settings.value('fromCode', 'USD') - toCode = settings.value('toCode', 'EUR') - multiplier = settings.value('multiplier', 1) - numDecimals = settings.value('numDecimals', 4) - rate = settings.value('rate', 1.0) - workOffline = settings.value('workOffline', false) - if(!isOnline && !workOffline) { - networkIFace.openConnection() + /*var available = {} + for(var i = 0; i < availableCurrencies.length; i++) { + //console.log('Available:', JSON.stringify(availableCurrencies[i])) + available[availableCurrencies[i].toCode] = { rate: availableCurrencies[i].rate } + }*/ + + Currencies.available = availableCurrencies + //Currencies.available = available + } + onError: { + console.log('App.provider.onError:', error, message) + Env.setBusy(false) } - // NOTE: Is 'locale' used? - currenciesFetcher.request({'locale': locale}) - getRate() - console.log('App.Ready', fromCode, toCode) - setBusy(false) } - // TODO: This method needs to be generalized to allow for - // other providers + /*Component.onCompleted: { + }*/ + function getRate() { var response, doUpdate = false - if(isBusy) return - - setBusy(true) - - // Try to get it from the cache - storage.getRate(fromCode, toCode, function(response) { - //console.log('App.getRate()', response) - if(response.rate) { - //console.log('App.getRate(). rate:', response.rate) - var now, then - tmpResult = parseFloat(response['rate']).toFixed(numDecimals) - now = new Date() - then = new Date(response['date']) - - // Is it older than a 36 hrs?' - // Using 36 instead of 24 to avoid too many requests. - if(now.getTime() - then.getTime() > 129600000) { - // Also test if it's weekend, as the rates aren't updated then. - if(0 < now.getDay() < 6) { - console.log("It's a WEEKDAY") - doUpdate = workOffline ? false : true - } else { - console.log("It's WEEKEND") - } - } - setBusy(false) - } else { - console.log('App.getRate(). Nothing cached') - // Nothing cached - doUpdate = true - } - - if(doUpdate && !workOffline) { - if(isOnline) { - rateFetcher.request( {'from': fromCode, 'to': toCode} ) - } else { - console.log('Network is down') - notifier.notify(qsTr('Network is down')) - setBusy(false) - } - } else if(doUpdate) { - setBusy(false) - var str = qsTr("You have chosen to work offline, but the currency combination \ - %1 => %2 is not in the cache.").arg(fromCode).arg(toCode); - - pageStack.push(Qt.resolvedUrl('pages/SettingsDialog.qml'), {info: str}) - } - }) + //console.log('App.getRate. Busy or !Ready?', (Env.isBusy || !Env.isReady)) + if(Env.isBusy || !Env.isReady) { + console.log('App.GetRate. Returning!!!!') + return + } + console.log('App.getRate(' + fromCode + ', ' + toCode + ')') settings.fromCode = fromCode settings.toCode = toCode settings.multiplier = multiplier - } - - function setBusy(state) { - isBusy = state; + Env.setBusy(true) + provider.getRate(fromCode, toCode) } } diff --git a/qml/pages/AboutPage.qml b/qml/pages/AboutPage.qml index 5c9f6d0..bc80753 100644 --- a/qml/pages/AboutPage.qml +++ b/qml/pages/AboutPage.qml @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2018 Thomas Tanghus + Copyright (C) 2013-2019 Thomas Tanghus All rights reserved. You may use this file under the terms of BSD license as follows: diff --git a/qml/pages/FrontPage.qml b/qml/pages/FrontPage.qml index e737b6b..3ad52bd 100644 --- a/qml/pages/FrontPage.qml +++ b/qml/pages/FrontPage.qml @@ -28,30 +28,63 @@ */ import QtQuick 2.6 -//import QtQml 2.13 -import QtQml 2.2 +import QtQuick.Layouts 1.1 import Sailfish.Silica 1.0 import '../components' Page { id: frontPage; - allowedOrientations: Orientation.Portrait | Orientation.Landscape //defaultAllowedOrientations + property bool isEnabled: true + property var currentPair + + Binding { + target: frontPage + property: 'currentPair' + value: app.currentPair + } + + allowedOrientations: Orientation.All + + // This is triggered in App.provider.onRateRecieved + onCurrentPairChanged: { + console.log('FrontPage.currentPair:',currentPair.from, currentPair.to) + var from = Currencies.createCurrency(currentPair.from) + var to = Currencies.createCurrency(currentPair.to) + // Trigger the combos to adjust properties + if(Env.isReady && !Env.isBusy) { + fromCombo.activated(from) + toCombo.activated(to) + } + } + + onIsEnabledChanged: console.log('frontPage.isEnabled: ', isEnabled) + + Binding { + target: frontPage + property: 'isEnabled' + value: Env.isReady + // when: Env.isReady + // delayed: true + } Timer { - // This is used to update result - // but only after a short delay - id: inputTimer; - interval: 300; - running: false; - repeat: false; + // This is used to update result but only after a short delay + id: inputTimer + interval: 300 + running: false + repeat: false + property alias text: amountText.text onTriggered: { - multiplier = parseFloat(amountText.text); - //Qt.callLater(getRate); - getRate(); + if(text.trim().length > 0 && !isNaN(text) && parseFloat(text) > 0.0) { + multiplier = parseFloat(amountText.text) + if(!Env.isBusy) { getRate() } + } else { + restart() + } } } - // To enable PullDownMenu, place our content in a SilicaFlickable + // To enable PullDownMenu, place the content in a SilicaFlickable SilicaFlickable { anchors.fill: parent // Tell SilicaFlickable the height of its content. @@ -59,6 +92,8 @@ Page { // PullDownMenu and PushUpMenu must be declared in SilicaFlickable, SilicaListView or SilicaGridView PullDownMenu { + // TODO "Pulsate" menu when busy. Shouldn't 'busy' do that? + busy: Env.isBusy MenuItem { text: workOffline ? qsTr('Work online') : qsTr('Work offline') onClicked: { @@ -67,31 +102,24 @@ Page { } MenuItem { text: qsTr('Switch currencies') - onClicked: { - setBusy(true) - var from = fromCombo.currentIndex - fromCombo.currentIndex = toCombo.currentIndex - toCombo.currentIndex = from - - // Trigger activation - fromCombo.currentCurrency = fromCombo.currentItem.code - toCombo.currentCurrency = toCombo.currentItem.code - setBusy(false) - // And go - getRate() - } + enabled: isEnabled + onClicked: switchCurrencies() } - // FIXME: Menu 'Update' doesn't work + MenuItem { text: qsTr('Update') + enabled: isEnabled onClicked: { console.log('FrontPage menu Update:') - getRate() + storage.removeRate(fromCode, toCode, + function(rows) { + app.getRate()}) } } } PushUpMenu { + busy: Env.isBusy MenuItem { text: qsTr('Settings'); onClicked: { @@ -104,15 +132,9 @@ Page { pageStack.push(Qt.resolvedUrl('AboutPage.qml')) } } - MenuItem { - text: qsTr('Test') - onClicked: { - pageStack.push(Qt.resolvedUrl('SearchPage.qml')) - } - } } - // Place our content in a Column. The PageHeader is always placed at the top + // Place the content in a Column. The PageHeader is always placed at the top // of the page, followed by our content. Column { id: column @@ -121,106 +143,194 @@ Page { spacing: Theme.paddingLarge anchors.centerIn: parent PageHeader { + id: pageHeader title: qsTr('Currency Converter') } CurrencyCombo { id: fromCombo //: The currency to convert from label: qsTr('From') - currentCurrency: fromCode + enabled: isEnabled + currentCurrencyCode: fromCode onActivated: { - console.log('fromCombo', idx, currency.code, currency.getSymbol()) + console.log('FrontPage.fromCombo.onActivated:', JSON.stringify(currency)) fromCode = currency.code - fromSymbol = currency.getSymbol() - getRate() + fromSymbol = currency.symbol ? currency.symbol : currency.code + if(fromCode !== toCode && !Env.isBusy && Env.isReady) { app.getRate() } + } + } + // The iconButton, including animations, is "borrowed" + // from https://github.com/dgrr/harbour-translate/blob/master/qml/pages/MainPage.qml + // Thanks, dgrr (: + IconButton { + id: iconButton + enabled: isEnabled + opacity: (enabled ? 1 : 0) + anchors { + //top: fromCombo.bottom + horizontalCenter: parent.horizontalCenter + } + icon.source: "image://theme/icon-m-data-download?" + + (pressed ? Theme.highlightColor : Theme.primaryColor) + onClicked: { + rotationAnimation.start() + hideAnimation.start() + switchCurrencies() + } + + states: State { + when: page.orientation === Orientation.Landscape + /*AnchorChanges { + target: iconButton + //anchors.top: pageHeader.bottom + }*/ + PropertyChanges { + target: iconButton + rotation: 90 + } + } + + transitions: Transition { + ParallelAnimation { + AnchorAnimation { + duration: 300 + } + RotationAnimation { + duration: 300 + direction: RotationAnimation.Clockwise + } + } + } + + RotationAnimator { + id: rotationAnimation + target: iconButton + from: 0 + to: 360 + duration: 300 + running: false } } CurrencyCombo { id: toCombo //: The currency to convert to label: qsTr('To') - currentCurrency: toCode + enabled: isEnabled + currentCurrencyCode: toCode onActivated: { - console.log('toCombo', idx, currency.code, currency.getSymbol()) toCode = currency.code - toSymbol = currency.getSymbol() - getRate() + toSymbol = currency.symbol ? currency.symbol : currency.code + if(fromCode !== toCode && !Env.isBusy && Env.isReady) { app.getRate() } } } - Row { + ParallelAnimation { + id: hideAnimation + running: false + onStopped: { + //var v = box1.value + //box1.value = box2.value + //box2.value = v + pumpAnimation.start() + } + OpacityAnimator { + target: toCombo + from: 1 + to: 0 + } + OpacityAnimator { + target: toCombo + from: 1 + to: 0 + } + } + ParallelAnimation { + id: pumpAnimation + running: false + OpacityAnimator { + target: fromCombo + from: 0 + to: 1 + } + OpacityAnimator { + target: toCombo + from: 0 + to: 1 + } + } + + // https://doc.qt.io/qt-5/qml-qtquick-layouts-rowlayout.html ? + Flow { id: resultItem anchors.horizontalCenter: parent.horizontalCenter - //anchors.top: toCombo.bottom; - //anchors.topMargin: Theme.paddingLarge; Label { id: fromSymbolLabel; text: fromSymbol; - //anchors.leftMargin: Theme.paddingLarge; - //anchors.top: parent.top; - //anchors.left: parent.left; + verticalAlignment: Text.AlignBottom + horizontalAlignment: Text.AlignRight + topPadding: Theme.paddingSmall } + // https://doc.qt.io/qt-5/qml-qtquick-textinput.html ? TextField { id: amountText; text: multiplier; - label: qsTr('Amount') + enabled: isEnabled placeholderText: label - //anchors.left: fromSymbolLabel.right; - //anchors.rightMargin: fromSymbolLabel.right; - width: Math.round(frontPage.width/3.5) - horizontalAlignment: TextInput.AlignRight; + width: resultLabel.width // Math.round(frontPage.width/3.5) + //height: parent.height + horizontalAlignment: TextInput.AlignHCenter + //_editor.verticalAlignment: TextInput.AlignTop inputMethodHints: Qt.ImhFormattedNumbersOnly; validator: DoubleValidator { bottom: 0.1 decimals: numDecimals notation: DoubleValidator.StandardNotation - //locale: + } + onClicked: { + if(!selectedText) { + selectAll() + } } onTextChanged: { // Try not to refresh on every change. - //console.log('Result 1:', text) if(text.trim().length > 0 && !isNaN(text) && parseFloat(text) > 0.0) { inputTimer.restart(); - } else if(isNaN(text)) { // || text.trim().length === 0) { - text = 1 - }/* else if(parseFloat(text) === 0.0) { - console.log('Change', text, 'to', 1.0, '?') - }*/ - tmpResult = parseFloat(text) - //console.log('Result 2:', text) + } } - EnterKey.enabled: text.length > 0 && parseFloat(text) > 0.1 + EnterKey.enabled: text.length > 0 && !isNaN(text) && parseFloat(text) > 0.0 //EnterKey.iconSource: 'image://theme/icon-m-enter-next' EnterKey.iconSource: "image://theme/icon-m-enter-accept" } Label { - //anchors.left: amountText.right; + id: resultLabel + topPadding: Theme.paddingSmall //: Just localizing the result. NOT to be translated text: ' = ' + toSymbol + ' ' + qsTr("%L1").arg(result); horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignBottom; } - // Set the time updated. Use Date().toLocaleString(Qt.locale()) - /*Label { - width: parent.width; - wrapMode: Text.WrapAtWordBoundaryOrAnywhere; - font.pixelSize: Theme.fontSizeExtraSmall; - color: Theme.secondaryColor; - text: ""; - }*/ } + // Set the time updated. Use Date().toLocaleString(Qt.locale()) Label { anchors.horizontalCenter: parent.horizontalCenter - //anchors.top: resultItem.bottom; - //anchors.topMargin: Theme.paddingLarge - font.pixelSize: Theme.fontSizeExtraSmall - color: Theme.secondaryHighlightColor - text: (workOffline || !isOnline) - ? qsTr('Working offline') - : qsTr('Working online') + font.pixelSize: Theme.fontSizeExtraSmall; + color: Theme.secondaryHighlightColor; + text: ((workOffline || !Env.isOnline) ? qsTr('Offline') : qsTr('Online')) + + ', '+ qsTr('Date: ') + + new Date(dateRecieved).toLocaleString(Qt.locale(locale), Locale.NarrowFormat) + + ' UTC' } } } -} - + function switchCurrencies() { + var from = fromCombo.currentCurrencyCode + fromCombo.currentCurrencyCode = toCombo.currentCurrencyCode + toCombo.currentCurrencyCode = from + // NOTE: Trigger activation. Forget why I need this..? + fromCombo.currentCurrencyCode = fromCombo.currentCurrency.code + toCombo.currentCurrencyCode = toCombo.currentCurrency.code + // And go + app.getRate() + } +} diff --git a/qml/pages/SearchPage.qml b/qml/pages/SearchPage.qml deleted file mode 100644 index a7f6241..0000000 --- a/qml/pages/SearchPage.qml +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************************** -** -** Copyright (C) 2013 Jolla Ltd. -** Contact: Joona Petrell -** All rights reserved. -** -** This file is part of Sailfish Silica UI component package. -** -** You may use this file under the terms of BSD license as follows: -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** * Neither the name of the Jolla Ltd nor the -** names of its contributors may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR -** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -****************************************************************************************/ - -import QtQuick 2.6 -import Sailfish.Silica 1.0 -import "../components" - -Page { - id: searchPage - property string searchString - property bool keepSearchFieldFocus - property variant translation - allowedOrientations: Orientation.All - - onTranslationChanged: { - console.log('Translation changed:', translation) - } - - Column { - id: headerContainer - - width: searchPage.width - - PageHeader { - title: 'Currencies' - } - - SearchField { - id: searchField - width: parent.width - - Binding { - target: searchPage - property: "searchString" - value: searchField.text.toLowerCase().trim() - } - } - } - - SilicaListView { - anchors { - fill: parent - leftMargin: Theme.paddingLarge - rightMargin: Theme.paddingLarge - topMargin: headerContainer.height + Theme.paddingLarge - } - - VerticalScrollDecorator {} - - JSONListModel { - id: jsonModel - source: 'https://api.exchangeratesapi.io/latest' - //source: Qt.resolvedUrl('../components/currencies.json') - } - model: jsonModel.model - - delegate: BackgroundItem { - id: backgroundItem - onClicked: console.log('Clicked on:', model.code) - - ListView.onAdd: AddAnimation { - target: backgroundItem - } - ListView.onRemove: RemoveAnimation { - target: backgroundItem - } - - Row { - spacing: Theme.paddingMedium - Image { - source: Qt.resolvedUrl("../../flags/" + model.code.toLowerCase() + ".png") - anchors.verticalCenter: parent.verticalCenter - fillMode: Image.PreserveAspectFit - } - Label { - anchors.verticalCenter: parent.verticalCenter - color: Theme.secondaryHighlightColor - textFormat: Text.StyledText - text: model.code + ': ' + translation[model.code].name // model.rate - } - } - } - } - - function getCurrencyTranslation() { - var locale = Qt.locale().name - if(locale === 'C') { - locale = 'en_GB' - } - - var url = Qt.resolvedUrl('../../data/currencies_{locale}.json'.replace('{locale}', locale)) - console.log('Locale:', locale) - console.log('URL:', url) - var xhr = new XMLHttpRequest - xhr.open("GET", url) - xhr.onreadystatechange = function() { - console.log('xhr.readyState:', xhr.readyState, XMLHttpRequest.DONE) - console.log('xhr.status:', xhr.status, xhr.statusText) - if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { - console.log('Got it') - translation = JSON.parse(xhr.responseText) - } - } - xhr.send(); - } - - Component.onCompleted: { - translation = getCurrencyTranslation() - } -} diff --git a/qml/pages/SettingsDialog.qml b/qml/pages/SettingsDialog.qml index f8d37d3..7a9f7d2 100644 --- a/qml/pages/SettingsDialog.qml +++ b/qml/pages/SettingsDialog.qml @@ -47,22 +47,6 @@ Dialog { contentHeight: column.height VerticalScrollDecorator {} - /*Label { - id: infoBox - visible: info - parent: header.extraContent - //text: "Extra content" - text: info - font.pixelSize: Theme.fontSizeExtraSmall - wrapMode: Text.Wrap - //y: header.height //+ Theme.paddingMedium - width: settingsDialog.width - (Theme.paddingMedium * 2) - anchors.horizontalCenter: parent.horizontalCenter - padding: Theme.horizontalPageMargin - //anchors.top: header.bottom - anchors.leftMargin: Theme.paddingLarge - anchors.rightMargin: Theme.paddingLarge - }*/ PullDownMenu { MenuItem { //: Remove the cached conversions @@ -93,12 +77,6 @@ Dialog { width: parent.width - (Theme.paddingMedium * 2) spacing: Theme.horizontalPageMargin padding: Theme.paddingMedium //.horizontalPageMargin - /* - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: header.bottom - anchors.leftMargin: Theme.paddingLarge - anchors.rightMargin: Theme.paddingLarge - */ /*DialogHeader { id: header; @@ -136,16 +114,13 @@ Dialog { id: sectionProvidersGeneral text: qsTr('Exchange Rate Provider') } - //Column { - // anchors.fill: parent - ComboBox { - menu: ContextMenu { - MenuItem { text: "European Central Bank" } - MenuItem { text: "CurrencyLayer" } - MenuItem { text: "Fixer.io" } - } + ComboBox { + menu: ContextMenu { + MenuItem { text: "European Central Bank" } + MenuItem { text: "CurrencyLayer" } + MenuItem { text: "Fixer.io" } } - //} + } } } Component.onCompleted: { @@ -155,12 +130,6 @@ Dialog { } } onAccepted: { - console.log('tmpWorkOffline:', tmpWorkOffline) - console.log('workOffline:', workOffline) - console.log('workOffline !== tmpWorkOffline:', workOffline !== tmpWorkOffline) - console.log('isOnline:', isOnline) - console.log('All:', !tmpWorkOffline && workOffline !== tmpWorkOffline && !isOnline) - // If the user selected to work online, but the phone isn't // open the network connection dialog. if(workOffline && !tmpWorkOffline !== tmpWorkOffline && !isOnline) { diff --git a/src/harbour-currencyconverter.cpp b/src/harbour-currencyconverter.cpp index f4ceb04..85fc594 100644 --- a/src/harbour-currencyconverter.cpp +++ b/src/harbour-currencyconverter.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Thomas Tanghus + Copyright (C) 2013-2019 Thomas Tanghus All rights reserved. You may use this file under the terms of BSD license as follows: @@ -48,8 +48,12 @@ int main(int argc, char *argv[]) { //app->setApplicationVersion(QStringLiteral(VERSION_STRING)); QQuickView *view = SailfishApp::createView(); view->engine()->addImportPath(SailfishApp::pathTo("lib/").toLocalFile()); + qDebug() << "Components import path" << SailfishApp::pathTo("qml/components/").toLocalFile(); view->engine()->addImportPath(SailfishApp::pathTo("qml/components/").toLocalFile()); view->engine()->addImportPath(SailfishApp::pathTo("qml/pages/").toLocalFile()); + + //qmlRegisterSingletonType(SailfishApp::pathTo("qml/components/Env.qml"), "harbour.currencyconverter.environment", 0, 1, "Env"); + QTranslator *translator = new QTranslator; QString locale = QLocale::system().name(); @@ -62,6 +66,8 @@ int main(int argc, char *argv[]) { } app->installTranslator(translator); + // https://stackoverflow.com/questions/34109523/setting-localstorage-location-via-setofflinestoragepath + view->rootContext()->setContextProperty("root", SailfishApp::pathTo("./").toLocalFile()); view->setSource(SailfishApp::pathTo("qml/harbour-currencyconverter.qml")); view->showFullScreen(); return app->exec();