summaryrefslogtreecommitdiffstats
path: root/kmymoney2/dialogs/kcurrencycalculator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmymoney2/dialogs/kcurrencycalculator.cpp')
-rw-r--r--kmymoney2/dialogs/kcurrencycalculator.cpp315
1 files changed, 315 insertions, 0 deletions
diff --git a/kmymoney2/dialogs/kcurrencycalculator.cpp b/kmymoney2/dialogs/kcurrencycalculator.cpp
new file mode 100644
index 0000000..6e674dc
--- /dev/null
+++ b/kmymoney2/dialogs/kcurrencycalculator.cpp
@@ -0,0 +1,315 @@
+/***************************************************************************
+ kcurrencycalculator.cpp - description
+ -------------------
+ begin : Thu Apr 8 2004
+ copyright : (C) 2000-2004 by Michael Edwardes
+ Javier Campos Morales <[email protected]>
+ Felix Rodriguez <[email protected]>
+ Thomas Baumgart <[email protected]>
+ Kevin Tambascio <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// ----------------------------------------------------------------------------
+// QT Includes
+
+#include <qlabel.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include <qwidgetstack.h>
+#include <qgroupbox.h>
+
+// ----------------------------------------------------------------------------
+// KDE Includes
+
+#include <klocale.h>
+#include <kpushbutton.h>
+#include <kcombobox.h>
+#include <kstdguiitem.h>
+
+// ----------------------------------------------------------------------------
+// Project Includes
+
+#include "kcurrencycalculator.h"
+
+#include <kmymoney/kmymoneyedit.h>
+#include <kmymoney/kmymoneydateinput.h>
+#include <kmymoney/kmymoneycurrencyselector.h>
+#include <kmymoney/mymoneyprice.h>
+#include <kmymoney/mymoneytransaction.h>
+#include <kmymoney/kmymoneyglobalsettings.h>
+
+#include "../kmymoneyutils.h"
+
+bool KCurrencyCalculator::setupSplitPrice(MyMoneyMoney& shares, const MyMoneyTransaction& t, const MyMoneySplit& s, const QMap<QString, MyMoneyMoney>& priceInfo, QWidget* parentWidget)
+{
+ bool rc = true;
+ MyMoneyFile* file = MyMoneyFile::instance();
+
+ if(!s.value().isZero()) {
+ MyMoneyAccount cat = file->account(s.accountId());
+ MyMoneySecurity toCurrency;
+ toCurrency = file->security(cat.currencyId());
+ // determine the fraction required for this category/account
+ int fract = cat.fraction(toCurrency);
+
+ if(cat.currencyId() != t.commodity()) {
+
+ MyMoneySecurity fromCurrency;
+ MyMoneyMoney fromValue, toValue;
+ fromCurrency = file->security(t.commodity());
+ // display only positive values to the user
+ fromValue = s.value().abs();
+
+ // if we had a price info in the beginning, we use it here
+ if(priceInfo.find(cat.currencyId()) != priceInfo.end()) {
+ toValue = (fromValue * priceInfo[cat.currencyId()]).convert(fract);
+ }
+
+ // if the shares are still 0, we need to change that
+ if(toValue.isZero()) {
+ MyMoneyPrice price = file->price(fromCurrency.id(), toCurrency.id());
+ // if the price is valid calculate the shares. If it is invalid
+ // assume a conversion rate of 1.0
+ if(price.isValid()) {
+ toValue = (price.rate(toCurrency.id()) * fromValue).convert(fract);
+ } else {
+ toValue = fromValue;
+ }
+ }
+
+ // now present all that to the user
+ KCurrencyCalculator calc(fromCurrency,
+ toCurrency,
+ fromValue,
+ toValue,
+ t.postDate(),
+ fract,
+ parentWidget, "currencyCalculator");
+
+ if(calc.exec() == QDialog::Rejected) {
+ rc = false;
+ } else
+ shares = (s.value() * calc.price()).convert(fract);
+
+ } else {
+ shares = s.value().convert(fract);
+ }
+ } else
+ shares = s.value();
+
+ return rc;
+}
+
+KCurrencyCalculator::KCurrencyCalculator(const MyMoneySecurity& from, const MyMoneySecurity& to, const MyMoneyMoney& value, const MyMoneyMoney& shares, const QDate& date, const signed64 resultFraction, QWidget *parent, const char *name ) :
+ KCurrencyCalculatorDecl(parent, name),
+ m_fromCurrency(from),
+ m_toCurrency(to),
+ m_result(shares.abs()),
+ m_value(value.abs()),
+ m_resultFraction(resultFraction)
+{
+ MyMoneyFile* file = MyMoneyFile::instance();
+
+ m_dateFrame->hide();
+ if(date.isValid())
+ m_dateEdit->setDate(date);
+ else
+ m_dateEdit->setDate(QDate::currentDate());
+
+ m_fromCurrencyText->setText(m_fromCurrency.isCurrency() ? m_fromCurrency.id() : m_fromCurrency.tradingSymbol());
+ m_toCurrencyText->setText(m_toCurrency.isCurrency() ? m_toCurrency.id() : m_toCurrency.tradingSymbol());
+
+ m_fromAmount->setText(m_value.formatMoney("", MyMoneyMoney::denomToPrec(m_fromCurrency.smallestAccountFraction())));
+
+ m_dateText->setText(KGlobal::locale()->formatDate(date, true));
+
+ m_fromType->setText(KMyMoneyUtils::securityTypeToString(m_fromCurrency.securityType()));
+ m_toType->setText(KMyMoneyUtils::securityTypeToString(m_toCurrency.securityType()));
+
+ // load button icons
+ m_cancelButton->setGuiItem(KStdGuiItem::cancel());
+ m_okButton->setGuiItem(KStdGuiItem::ok());
+
+ m_updateButton->setChecked(KMyMoneyGlobalSettings::priceHistoryUpdate());
+
+ // setup initial result
+ if(m_result == MyMoneyMoney() && !m_value.isZero()) {
+ MyMoneyPrice pr = file->price(m_fromCurrency.id(), m_toCurrency.id(), date);
+ if(pr.isValid()) {
+ m_result = m_value * pr.rate(m_fromCurrency.id());
+ }
+ }
+
+ // fill in initial values
+ m_toAmount->loadText(m_result.formatMoney("", MyMoneyMoney::denomToPrec(m_resultFraction)));
+ m_toAmount->setPrecision(MyMoneyMoney::denomToPrec(m_resultFraction));
+
+ m_conversionRate->setPrecision(KMyMoneyGlobalSettings::pricePrecision());
+
+ connect(m_amountButton, SIGNAL(clicked()), this, SLOT(slotSetToAmount()));
+ connect(m_rateButton, SIGNAL(clicked()), this, SLOT(slotSetExchangeRate()));
+
+ connect(m_toAmount, SIGNAL(valueChanged(const QString&)), this, SLOT(slotUpdateResult(const QString&)));
+ connect(m_conversionRate, SIGNAL(valueChanged(const QString&)), this, SLOT(slotUpdateRate(const QString&)));
+ connect(m_cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
+ connect(m_okButton, SIGNAL(clicked()), this, SLOT(accept()));
+
+ // use this as the default
+ m_amountButton->animateClick();
+ slotUpdateResult(m_toAmount->text());
+
+ // If the from security is not a currency, we only allow entering a price
+ if(!m_fromCurrency.isCurrency()) {
+ m_rateButton->animateClick();
+ m_amountButton->hide();
+ m_toAmount->hide();
+ }
+ m_okButton->setFocus();
+}
+
+KCurrencyCalculator::~KCurrencyCalculator()
+{
+}
+
+void KCurrencyCalculator::setupPriceEditor(void)
+{
+ m_dateFrame->show();
+ m_amountDateFrame->hide();
+ m_updateButton->setChecked(true);
+ m_updateButton->hide();
+}
+
+void KCurrencyCalculator::slotSetToAmount(void)
+{
+ m_rateButton->setChecked(false);
+ m_toAmount->setEnabled(true);
+ m_conversionRate->setEnabled(false);
+}
+
+void KCurrencyCalculator::slotSetExchangeRate(void)
+{
+ m_amountButton->setChecked(false);
+ m_toAmount->setEnabled(false);
+ m_conversionRate->setEnabled(true);
+}
+
+void KCurrencyCalculator::slotUpdateResult(const QString& /*txt*/)
+{
+ MyMoneyMoney result = m_toAmount->value();
+ MyMoneyMoney price(0, 1);
+
+ if(result.isNegative()) {
+ m_toAmount->setValue(-result);
+ slotUpdateResult(QString());
+ return;
+ }
+
+ if(!result.isZero()) {
+ price = result / m_value;
+
+ m_conversionRate->loadText(price.formatMoney("", KMyMoneyGlobalSettings::pricePrecision()));
+ m_result = (m_value * price).convert(m_resultFraction);
+ m_toAmount->loadText(m_result.formatMoney("", MyMoneyMoney::denomToPrec(m_resultFraction)));
+ }
+ updateExample(price);
+}
+
+void KCurrencyCalculator::slotUpdateRate(const QString& /*txt*/)
+{
+ MyMoneyMoney price = m_conversionRate->value();
+
+ if(price.isNegative()) {
+ m_conversionRate->setValue(-price);
+ slotUpdateRate(QString());
+ return;
+ }
+
+ if(!price.isZero()) {
+ m_conversionRate->loadText(price.formatMoney("", KMyMoneyGlobalSettings::pricePrecision()));
+ m_result = (m_value * price).convert(m_resultFraction);
+ m_toAmount->loadText(m_result.formatMoney("", MyMoneyMoney::denomToPrec(m_resultFraction)));
+ }
+ updateExample(price);
+}
+
+void KCurrencyCalculator::updateExample(const MyMoneyMoney& price)
+{
+ QString msg;
+ if(price.isZero()) {
+ msg = QString("1 %1 = ? %2").arg(m_fromCurrency.tradingSymbol())
+ .arg(m_toCurrency.tradingSymbol());
+ if(m_fromCurrency.isCurrency()) {
+ msg += QString("\n");
+ msg += QString("1 %1 = ? %2").arg(m_toCurrency.tradingSymbol())
+ .arg(m_fromCurrency.tradingSymbol());
+ }
+ } else {
+ msg = QString("1 %1 = %2 %3").arg(m_fromCurrency.tradingSymbol())
+ .arg(price.formatMoney("", KMyMoneyGlobalSettings::pricePrecision()))
+ .arg(m_toCurrency.tradingSymbol());
+ if(m_fromCurrency.isCurrency()) {
+ msg += QString("\n");
+ msg += QString("1 %1 = %2 %3").arg(m_toCurrency.tradingSymbol())
+ .arg((MyMoneyMoney(1,1)/price).formatMoney("", KMyMoneyGlobalSettings::pricePrecision()))
+ .arg(m_fromCurrency.tradingSymbol());
+ }
+ }
+ m_conversionExample->setText(msg);
+ m_okButton->setEnabled(!price.isZero());
+}
+
+void KCurrencyCalculator::accept(void)
+{
+ if(m_conversionRate->isEnabled())
+ slotUpdateRate(QString());
+ else
+ slotUpdateResult(QString());
+
+ if(m_updateButton->isChecked()) {
+ MyMoneyPrice pr = MyMoneyFile::instance()->price(m_fromCurrency.id(), m_toCurrency.id(), m_dateEdit->date());
+ if(!pr.isValid()
+ || pr.date() != m_dateEdit->date()
+ || (pr.date() == m_dateEdit->date() && pr.rate(m_fromCurrency.id()) != price())) {
+ pr = MyMoneyPrice(m_fromCurrency.id(), m_toCurrency.id(), m_dateEdit->date(), price(), i18n("User"));
+ MyMoneyFileTransaction ft;
+ try {
+ MyMoneyFile::instance()->addPrice(pr);
+ ft.commit();
+ } catch(MyMoneyException *e) {
+ qDebug("Cannot add price");
+ delete e;
+ }
+ }
+ }
+
+ // remember setting for next round
+ KMyMoneyGlobalSettings::setPriceHistoryUpdate(m_updateButton->isChecked());
+
+ KCurrencyCalculatorDecl::accept();
+}
+
+const MyMoneyMoney KCurrencyCalculator::price(void) const
+{
+ // This should fix https://bugs.kde.org/show_bug.cgi?id=205254 but
+ // I am not sure about any side effects when dealing with multi-
+ // currency transactions.
+ //
+ // The following line is the original version of this code
+ // which causes some rounding issues (see the above bug entry)
+ // return m_result / m_value;
+ return m_conversionRate->value();
+}
+
+
+#include "kcurrencycalculator.moc"