summaryrefslogtreecommitdiffstats
path: root/kmymoney2/dialogs/ksplittransactiondlg.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-07-04 22:38:03 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-07-04 22:38:03 +0000
commitdadc34655c3ab961b0b0b94a10eaaba710f0b5e8 (patch)
tree99e72842fe687baea16376a147619b6048d7e441 /kmymoney2/dialogs/ksplittransactiondlg.cpp
downloadkmymoney-dadc34655c3ab961b0b0b94a10eaaba710f0b5e8.tar.gz
kmymoney-dadc34655c3ab961b0b0b94a10eaaba710f0b5e8.zip
Added kmymoney
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kmymoney@1239792 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kmymoney2/dialogs/ksplittransactiondlg.cpp')
-rw-r--r--kmymoney2/dialogs/ksplittransactiondlg.cpp449
1 files changed, 449 insertions, 0 deletions
diff --git a/kmymoney2/dialogs/ksplittransactiondlg.cpp b/kmymoney2/dialogs/ksplittransactiondlg.cpp
new file mode 100644
index 0000000..a197b4c
--- /dev/null
+++ b/kmymoney2/dialogs/ksplittransactiondlg.cpp
@@ -0,0 +1,449 @@
+/***************************************************************************
+ ksplittransactiondlg.cpp - description
+ -------------------
+ begin : Thu Jan 10 2002
+ copyright : (C) 2000-2002 by Michael Edwardes
+ email : mte@users.sourceforge.net
+ Javier Campos Morales <javi_c@users.sourceforge.net>
+ Felix Rodriguez <frodriguez@users.sourceforge.net>
+ John C <thetacoturtle@users.sourceforge.net>
+ Thomas Baumgart <ipwizard@users.sourceforge.net>
+ Kevin Tambascio <ktambascio@users.sourceforge.net>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 <qpushbutton.h>
+#include <qlabel.h>
+#include <qtable.h>
+#include <qtimer.h>
+#include <qptrlist.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qcursor.h>
+
+// ----------------------------------------------------------------------------
+// KDE Includes
+
+#include <kglobal.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kpushbutton.h>
+#include <kactivelabel.h>
+#include <kstdguiitem.h>
+#include <kapplication.h>
+
+// ----------------------------------------------------------------------------
+// Project Includes
+
+#include "ksplittransactiondlg.h"
+#include <kmymoney/kmymoneyedit.h>
+#include <kmymoney/kmymoneylineedit.h>
+#include <kmymoney/mymoneyfile.h>
+
+#include "kmymoneysplittable.h"
+#include "../dialogs/ksplitcorrectiondlg.h"
+
+KSplitTransactionDlg::KSplitTransactionDlg(const MyMoneyTransaction& t,
+ const MyMoneySplit& s,
+ const MyMoneyAccount& acc,
+ const bool amountValid,
+ const bool deposit,
+ const MyMoneyMoney& calculatedValue,
+ const QMap<QString, MyMoneyMoney>& priceInfo,
+ QWidget* parent, const char* name) :
+ KSplitTransactionDlgDecl(parent, name, true),
+ m_account(acc),
+ m_split(s),
+ m_precision(2),
+ m_amountValid(amountValid),
+ m_isDeposit(deposit),
+ m_calculatedValue(calculatedValue)
+{
+ // add icons to buttons
+ KIconLoader *il = KGlobal::iconLoader();
+
+ KGuiItem clearButtenItem( i18n( "Clear &All" ),
+ QIconSet(il->loadIcon("edittrash", KIcon::Small, KIcon::SizeSmall)),
+ i18n("Clear all splits"),
+ i18n("Use this to clear all splits of this transaction"));
+ clearAllBtn->setGuiItem(clearButtenItem);
+
+
+ KGuiItem mergeButtenItem( i18n( "&Merge" ),
+ QIconSet(il->loadIcon("math_sum", KIcon::Small, KIcon::SizeSmall)),
+ "", "");
+ mergeBtn->setGuiItem(mergeButtenItem);
+
+ // make finish the default
+ finishBtn->setDefault(true);
+
+ // setup the focus
+ cancelBtn->setFocusPolicy(QWidget::NoFocus);
+ finishBtn->setFocusPolicy(QWidget::NoFocus);
+ clearAllBtn->setFocusPolicy(QWidget::NoFocus);
+
+ // connect signals with slots
+ connect(transactionsTable, SIGNAL(transactionChanged(const MyMoneyTransaction&)),
+ this, SLOT(slotSetTransaction(const MyMoneyTransaction&)));
+ connect(transactionsTable, SIGNAL(createCategory(const QString&, QString&)), this, SLOT(slotCreateCategory(const QString&, QString&)));
+ connect(transactionsTable, SIGNAL(objectCreation(bool)), this, SIGNAL(objectCreation(bool)));
+
+ connect(transactionsTable, SIGNAL(returnPressed()), this, SLOT(accept()));
+ connect(transactionsTable, SIGNAL(escapePressed()), this, SLOT(reject()));
+
+ connect(cancelBtn, SIGNAL(clicked()), this, SLOT(reject()));
+ connect(finishBtn, SIGNAL(clicked()), this, SLOT(accept()));
+ connect(clearAllBtn, SIGNAL(clicked()), this, SLOT(slotClearAllSplits()));
+ connect(mergeBtn, SIGNAL(clicked()), this, SLOT(slotMergeSplits()));
+ connect(clearZeroBtn, SIGNAL(clicked()), this, SLOT(slotClearUnusedSplits()));
+
+ // setup the precision
+ try {
+ MyMoneySecurity currency = MyMoneyFile::instance()->currency(t.commodity());
+ m_precision = MyMoneyMoney::denomToPrec(m_account.fraction(currency));
+ } catch(MyMoneyException *e) {
+ delete e;
+ }
+
+ slotSetTransaction(t);
+
+ // pass on those vars
+ transactionsTable->setup(priceInfo);
+
+ QSize size(width(), height());
+ kapp->config()->setGroup("SplitTransactionEditor");
+ size = kapp->config()->readSizeEntry("Geometry", &size);
+ size.setHeight(size.height()-1);
+ QDialog::resize( size.expandedTo(minimumSizeHint()) );
+
+ // Trick: it seems, that the initial sizing of the dialog does
+ // not work correctly. At least, the columns do not get displayed
+ // correct. Reason: the return value of transactionsTable->visibleWidth()
+ // is incorrect. If the widget is visible, resizing works correctly.
+ // So, we let the dialog show up and resize it then. It's not really
+ // clean, but the only way I got the damned thing working.
+ QTimer::singleShot( 10, this, SLOT(initSize()) );
+}
+
+KSplitTransactionDlg::~KSplitTransactionDlg()
+{
+ kapp->config()->setGroup("SplitTransactionEditor");
+ kapp->config()->writeEntry("Geometry", size());
+}
+
+int KSplitTransactionDlg::exec(void)
+{
+ // for deposits, we invert the sign of all splits.
+ // don't forget to revert when we're done ;-)
+ if(m_isDeposit) {
+ for(unsigned i = 0; i < m_transaction.splits().count(); ++i) {
+ MyMoneySplit split = m_transaction.splits()[i];
+ split.setValue(-split.value());
+ split.setShares(-split.shares());
+ m_transaction.modifySplit(split);
+ }
+ }
+
+ int rc;
+ do {
+ transactionsTable->setFocus();
+
+ // initialize the display
+ transactionsTable->setTransaction(m_transaction, m_split, m_account);
+ updateSums();
+
+ rc = KSplitTransactionDlgDecl::exec();
+
+ if(rc == QDialog::Accepted) {
+ if(!diffAmount().isZero()) {
+ KSplitCorrectionDlgDecl* corrDlg = new KSplitCorrectionDlgDecl(this, 0, true);
+
+ // add icons to buttons
+ corrDlg->okBtn->setGuiItem(KStdGuiItem::ok());
+ corrDlg->cancelBtn->setGuiItem(KStdGuiItem::cancel());
+
+ MyMoneySplit split = m_transaction.splits()[0];
+ QString total = (-split.value()).formatMoney("", m_precision);
+ QString sums = splitsValue().formatMoney("", m_precision);
+ QString diff = diffAmount().formatMoney("", m_precision);
+
+ // now modify the text items of the dialog to contain the correct values
+ QString q = i18n("The total amount of this transaction is %1 while "
+ "the sum of the splits is %2. The remaining %3 are "
+ "unassigned.")
+ .arg(total)
+ .arg(sums)
+ .arg(diff);
+ corrDlg->explanation->setText(q);
+
+ q = i18n("Change &total amount of transaction to %1.").arg(sums);
+ corrDlg->changeBtn->setText(q);
+
+ q = i18n("&Distribute difference of %1 among all splits.").arg(diff);
+ corrDlg->distributeBtn->setText(q);
+ // FIXME remove the following line once distribution among
+ // all splits is implemented
+ corrDlg->distributeBtn->hide();
+
+
+ // if we have only two splits left, we don't allow leaving sth. unassigned.
+ if(m_transaction.splitCount() < 3) {
+ q = i18n("&Leave total amount of transaction at %1.").arg(total);
+ } else {
+ q = i18n("&Leave %1 unassigned.").arg(diff);
+ }
+ corrDlg->leaveBtn->setText(q);
+
+ if((rc = corrDlg->exec()) == QDialog::Accepted) {
+ QButton* button = corrDlg->buttonGroup->selected();
+ if(button != 0) {
+ switch(corrDlg->buttonGroup->id(button)) {
+ case 0: // continue to edit
+ rc = QDialog::Rejected;
+ break;
+
+ case 1: // modify total
+ split.setValue(-splitsValue());
+ split.setShares(-splitsValue());
+ m_transaction.modifySplit(split);
+ break;
+
+ case 2: // distribute difference
+ qDebug("distribution of difference not yet supported in KSplitTransactionDlg::slotFinishClicked()");
+ break;
+
+ case 3: // leave unassigned
+ break;
+ }
+ }
+ }
+ delete corrDlg;
+ }
+ } else
+ break;
+
+ } while(rc != QDialog::Accepted);
+
+ // for deposits, we inverted the sign of all splits.
+ // now we revert it back, so that things are left correct
+ if(m_isDeposit) {
+ for(unsigned i = 0; i < m_transaction.splits().count(); ++i) {
+ MyMoneySplit split = m_transaction.splits()[i];
+ split.setValue(-split.value());
+ split.setShares(-split.shares());
+ m_transaction.modifySplit(split);
+ }
+ }
+
+ return rc;
+}
+
+void KSplitTransactionDlg::initSize(void)
+{
+ QDialog::resize(width(), height()+1);
+}
+
+void KSplitTransactionDlg::accept()
+{
+ transactionsTable->slotCancelEdit();
+ KSplitTransactionDlgDecl::accept();
+}
+
+void KSplitTransactionDlg::reject()
+{
+ // cancel any edit activity in the split register
+ transactionsTable->slotCancelEdit();
+ KSplitTransactionDlgDecl::reject();
+}
+
+void KSplitTransactionDlg::slotClearAllSplits(void)
+{
+ transactionsTable->slotEndEdit();
+ int answer;
+ answer = KMessageBox::warningContinueCancel (this,
+ i18n("You are about to delete all splits of this transaction. "
+ "Do you really want to continue?"),
+ i18n("KMyMoney"),
+ i18n("Continue")
+ );
+
+ if(answer == KMessageBox::Continue) {
+ transactionsTable->slotCancelEdit();
+ QValueList<MyMoneySplit> list = transactionsTable->getSplits(m_transaction);
+ QValueList<MyMoneySplit>::ConstIterator it;
+
+ // clear all but the one referencing the account
+ for(it = list.begin(); it != list.end(); ++it) {
+ m_transaction.removeSplit(*it);
+ }
+
+ transactionsTable->setTransaction(m_transaction, m_split, m_account);
+ slotSetTransaction(m_transaction);
+ }
+}
+
+void KSplitTransactionDlg::slotClearUnusedSplits(void)
+{
+ transactionsTable->slotEndEdit();
+
+ QValueList<MyMoneySplit> list = transactionsTable->getSplits(m_transaction);
+ QValueList<MyMoneySplit>::ConstIterator it;
+
+ try {
+ // remove all splits that don't have a value assigned
+ for(it = list.begin(); it != list.end(); ++it) {
+ if((*it).shares().isZero()) {
+ m_transaction.removeSplit(*it);
+ }
+ }
+
+ transactionsTable->setTransaction(m_transaction, m_split, m_account);
+ slotSetTransaction(m_transaction);
+ } catch(MyMoneyException* e) {
+ delete e;
+ }
+}
+
+void KSplitTransactionDlg::slotMergeSplits(void)
+{
+ transactionsTable->slotEndEdit();
+
+ QValueList<MyMoneySplit> list = transactionsTable->getSplits(m_transaction);
+ QValueList<MyMoneySplit>::ConstIterator it;
+
+ try {
+ // collect all splits, merge them if needed and remove from transaction
+ QValueList<MyMoneySplit> splits;
+ for(it = list.begin(); it != list.end(); ++it) {
+ QValueList<MyMoneySplit>::iterator it_s;
+ for(it_s = splits.begin(); it_s != splits.end(); ++it_s) {
+ if((*it_s).accountId() == (*it).accountId()
+ && (*it_s).memo().isEmpty() && (*it).memo().isEmpty())
+ break;
+ }
+ if(it_s != splits.end()) {
+ (*it_s).setShares((*it).shares() + (*it_s).shares());
+ (*it_s).setValue((*it).value() + (*it_s).value());
+ } else {
+ splits << *it;
+ }
+ m_transaction.removeSplit(*it);
+ }
+
+ // now add them back to the transaction
+ QValueList<MyMoneySplit>::iterator it_s;
+ for(it_s = splits.begin(); it_s != splits.end(); ++it_s) {
+ (*it_s).clearId();
+ m_transaction.addSplit(*it_s);
+ }
+
+ transactionsTable->setTransaction(m_transaction, m_split, m_account);
+ slotSetTransaction(m_transaction);
+ } catch(MyMoneyException* e) {
+ delete e;
+ }
+}
+
+void KSplitTransactionDlg::slotSetTransaction(const MyMoneyTransaction& t)
+{
+ transactionsTable->slotCancelEdit();
+
+ m_transaction = t;
+ QValueList<MyMoneySplit> list = transactionsTable->getSplits(m_transaction);
+ QValueList<MyMoneySplit>::ConstIterator it;
+
+ // check if we can merge splits or not, have zero splits or not
+ QMap<QString, int> splits;
+ bool haveZeroSplit = false;
+ for(it = list.begin(); it != list.end(); ++it) {
+ splits[(*it).accountId()]++;
+ if(((*it).id() != m_split.id()) && ((*it).shares().isZero()))
+ haveZeroSplit = true;
+ }
+ QMap<QString, int>::const_iterator it_s;
+ for(it_s = splits.begin(); it_s != splits.end(); ++it_s) {
+ if((*it_s) > 1)
+ break;
+ }
+ mergeBtn->setDisabled(it_s == splits.end());
+ clearZeroBtn->setEnabled(haveZeroSplit);
+
+ updateSums();
+}
+
+void KSplitTransactionDlg::updateSums(void)
+{
+ MyMoneyMoney splits(splitsValue());
+
+ if(m_amountValid == false) {
+ m_split.setValue(-splits);
+ m_transaction.modifySplit(m_split);
+ }
+
+ splitSum->setText("<b>" + splits.formatMoney("", m_precision) + " ");
+ splitUnassigned->setText("<b>" + diffAmount().formatMoney("", m_precision) + " ");
+ transactionAmount->setText("<b>" + (-m_split.value()).formatMoney("", m_precision) + " ");
+}
+
+MyMoneyMoney KSplitTransactionDlg::splitsValue(void)
+{
+ MyMoneyMoney splitsValue(m_calculatedValue);
+ QValueList<MyMoneySplit> list = transactionsTable->getSplits(m_transaction);
+ QValueList<MyMoneySplit>::ConstIterator it;
+
+ // calculate the current sum of all split parts
+ for(it = list.begin(); it != list.end(); ++it) {
+ if((*it).value() != MyMoneyMoney::autoCalc)
+ splitsValue += (*it).value();
+ }
+
+ return splitsValue;
+}
+
+MyMoneyMoney KSplitTransactionDlg::diffAmount(void)
+{
+ MyMoneyMoney diff(0);
+
+ // if there is an amount specified in the transaction, we need to calculate the
+ // difference, otherwise we display the difference as 0 and display the same sum.
+ if(m_amountValid) {
+ MyMoneySplit split = m_transaction.splits()[0];
+
+ diff = -(splitsValue() + split.value());
+ }
+ return diff;
+}
+
+void KSplitTransactionDlg::slotCreateCategory(const QString& name, QString& id)
+{
+ MyMoneyAccount acc, parent;
+ acc.setName(name);
+
+ if(m_isDeposit)
+ parent = MyMoneyFile::instance()->income();
+ else
+ parent = MyMoneyFile::instance()->expense();
+
+ // TODO extract possible first part of a hierarchy and check if it is one
+ // of our top categories. If so, remove it and select the parent
+ // according to this information.
+
+ emit createCategory(acc, parent);
+
+ // return id
+ id = acc.id();
+}
+
+#include "ksplittransactiondlg.moc"