File indexing completed on 2024-04-28 09:45:44

0001 /***************************************************************************
0002                           table.cpp  -  conversion table
0003                              -------------------
0004     begin                : jeu nov 23 21:03:30 CET 2006
0005     copyright            : (C) 2006-2022 by Éric Bischoff
0006     email                : bischoff@kde.org
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *                                                                         *
0011  *   This program is free software; you can redistribute it and/or modify  *
0012  *   it under the terms of the GNU General Public License as published by  *
0013  *   the Free Software Foundation; either version 2 of the License, or     *
0014  *   (at your option) any later version.                                   *
0015  *                                                                         *
0016  ***************************************************************************/
0017 
0018 #include "table.h"
0019 
0020 #include <QDBusConnection>
0021 #include <QDebug>
0022 
0023 #include <stdio.h>
0024 #include <stdlib.h>
0025 #include <math.h>
0026 
0027 // Constructor
0028 CurrencyTable::CurrencyTable(const QString &tablePath)
0029     : QObject(),
0030       path( tablePath ),
0031       currencies(),
0032       rounding( NO_ROUNDING )
0033 {
0034     QDBusConnection::sessionBus().registerObject(path, this, QDBusConnection::ExportScriptableSlots);
0035 
0036     qDebug() << QStringLiteral("curconvd: table \"%1\" created\n").arg(path);
0037 }
0038 
0039 // Destructor
0040 CurrencyTable::~CurrencyTable()
0041 {
0042     QDBusConnection::sessionBus().unregisterObject(path);
0043 
0044     qDebug() << QStringLiteral("curconvd: table \"%1\" destroyed\n").arg(path);
0045 }
0046 
0047 // Load currencies from data source
0048 void CurrencyTable::loadSource(const QString &dataSource, const QString &roundingMethod)
0049 {
0050     if ( !currencies.readCurrencies( "currencies.xml" ) )
0051     {
0052         fprintf(stderr, "Cannot load currencies.xml" );
0053         exit(1);
0054 // TODO: Less violent exit
0055     }
0056     currencies.clearRates();
0057 
0058     if (roundingMethod == "official rules")
0059         rounding = OFFICIAL_RULES;
0060     else if (roundingMethod == "smallest coin")
0061         rounding = SMALLEST_COIN;
0062     else
0063         rounding = NO_ROUNDING;
0064 
0065         connect( &currencies, SIGNAL(endDownload(int,QString)),
0066                  this, SLOT(endDownload(int,QString))
0067                );
0068 
0069     if (dataSource == "(fixed)")
0070     {
0071         currencies.addFixedRates( rounding );
0072         // endDownload is called here
0073     }
0074     else if (dataSource == "http://www.ecb.int")
0075     {
0076         currencies.addFixedRates( rounding, true );
0077         // endDownload is called here for the first time
0078         currencies.addECBRates( rounding );
0079         // endDowload is called again when completed
0080     }
0081 //  else if (dataSource == "http://www.newyorkfed.org")
0082 //  {
0083 //      currencies.addNY_FRBRates( rounding );
0084 //      // endDowload is called when completed
0085 //  }
0086     else if (dataSource == "http://rss.timegenie.com")
0087     {
0088         currencies.addFixedRates( rounding, true );
0089         // endDownload is called here for the first time
0090         currencies.addTGRates( rounding );
0091         // endDowload is called again when completed
0092     }
0093 }
0094 
0095 // Download has ended
0096 void CurrencyTable::endDownload(int defaultCurrency, const QString &date)
0097 {
0098 (void) defaultCurrency;
0099 (void) date;
0100 qDebug() << "curconvd: end of download not implemented yet!";
0101 // TODO: if defaultCurrency is not null, inform that a result is available
0102 }
0103 
0104 // List currencies handled
0105 QStringList CurrencyTable::AvailableCurrencies()
0106 {
0107     QStringList codes;
0108 
0109     printf( "curconvd: %s/AvailableCurrencies()\n",
0110         path.toUtf8().data());
0111 
0112     for (int num = 0; num < currencies.number(); num++)
0113         if ( currencies.position(num) == -2 )
0114             codes << QString(currencies.code(num));
0115 
0116     return codes;
0117 }
0118 
0119 // Gives the everyday symbol for a given currency code 
0120 QString CurrencyTable::Symbol(const QString &currencyCode)
0121 {
0122     QString currencySymbol;
0123     int num;
0124 
0125     printf( "curconvd: %s/Symbol(\"%s\")\n",
0126         path.toUtf8().data(),
0127         currencyCode.toUtf8().data());
0128 
0129     for (num = 0; num < currencies.number(); ++num)
0130         if ( currencies.code(num) == currencyCode )
0131             break;
0132     if (num == currencies.number())
0133         currencySymbol = ""; // TODO: return an error code here
0134     else
0135         currencySymbol = currencies.symbol(num);
0136 
0137     return currencySymbol;
0138 }
0139 
0140 // Gives the description for a given currency code
0141 QString CurrencyTable::Name(const QString &currencyCode)
0142 {
0143     QString currencyName;
0144     int num;
0145 
0146     printf( "curconvd: %s/Name(\"%s\")\n",
0147         path.toUtf8().data(),
0148         currencyCode.toUtf8().data());
0149 
0150     for (num = 0; num < currencies.number(); ++num)
0151         if ( currencies.code(num) == currencyCode )
0152             break;
0153     if (num == currencies.number())
0154         currencyName = ""; // TODO: return an error code here
0155     else
0156         currencyName = currencies.name(num);
0157 
0158     return currencyName;
0159 }
0160 
0161 // Convert an amount expressed in the reference currency
0162 double CurrencyTable::ConvertFromReference(const QString &currencyCode, double referenceValue)
0163 {
0164     double currencyValue;
0165     int num;
0166 
0167     printf( "curconvd: %s/ConvertFromReference(\"%s\", %g)\n",
0168         path.toUtf8().data(),
0169         currencyCode.toUtf8().data(),
0170         referenceValue);
0171 
0172     for (num = 0; num < currencies.number(); ++num)
0173         if ( currencies.code(num) == currencyCode )
0174             break;
0175     if (num == currencies.number())
0176         currencyValue = 0.0; // TODO: return an error code here
0177     else
0178     {
0179         double currencyRate, currencyPrecision;
0180 
0181         currencyRate = currencies.rate(num);
0182         switch (rounding)
0183         {
0184             case OFFICIAL_RULES:
0185                 currencyPrecision = currencies.officialRulesPrecision(num);
0186                 currencyValue = floor(referenceValue * currencyRate * 100.0 + 0.5)
0187                              / 100.0 * currencyPrecision;
0188                 break;
0189             case SMALLEST_COIN:
0190                 currencyPrecision = currencies.smallestCoinPrecision(num);
0191                 currencyValue = floor(referenceValue * currencyRate * 100.0 + 0.5)
0192                              / 100.0 * currencyPrecision;
0193                 break;
0194             default:
0195                 currencyValue = referenceValue * currencyRate;
0196         }
0197     }
0198 
0199     return currencyValue;
0200 }
0201 
0202 // Convert an amount expressed in the given currency
0203 double CurrencyTable::ConvertToReference(const QString &currencyCode, double currencyValue)
0204 {
0205     double referenceValue;
0206     int num;
0207 
0208     printf( "curconvd: %s/ConvertToReference(\"%s\", %g)\n",
0209         path.toUtf8().data(),
0210         currencyCode.toUtf8().data(),
0211         currencyValue);
0212 
0213     for (num = 0; num < currencies.number(); ++num)
0214         if ( currencies.code(num) == currencyCode )
0215             break;
0216     if (num == currencies.number())
0217         referenceValue = 0.0; // TODO: return an error code here
0218     else
0219     {
0220         double currencyRate, currencyPrecision;
0221 
0222         currencyRate = currencies.rate(num);
0223         switch (rounding)
0224         {
0225             case OFFICIAL_RULES:
0226                 currencyPrecision = currencies.officialRulesPrecision(num);
0227                 referenceValue = floor( currencyValue / currencyRate / currencyPrecision
0228                              * 100.0 + 0.5) / 100.0;
0229                 break;
0230             case SMALLEST_COIN:
0231                 currencyPrecision = currencies.smallestCoinPrecision(num);
0232                 referenceValue = floor( currencyValue / currencyRate / currencyPrecision
0233                              * 100.0 + 0.5) / 100.0;
0234                 break;
0235             default:
0236                 referenceValue = currencyValue / currencyRate;
0237         }
0238     }
0239 
0240     return referenceValue;
0241 }
0242 
0243 // Unload this currencies table
0244 void CurrencyTable::Unload()
0245 {
0246     qDebug() << QStringLiteral("curconvd: %1/Unload()").arg(path);
0247 
0248     delete this;
0249 }
0250 
0251 #include "moc_table.cpp"