|
|
|
/***************************************************************************
|
|
|
|
kinstitutionsview.cpp
|
|
|
|
-------------------
|
|
|
|
copyright : (C) 2005 by Thomas Baumgart
|
|
|
|
email : ipwizard@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 <tqheader.h>
|
|
|
|
#include <tqlabel.h>
|
|
|
|
#include <tqtabwidget.h>
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// KDE Includes
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Project Includes
|
|
|
|
|
|
|
|
#include <kmymoney/mymoneyfile.h>
|
|
|
|
#include "kinstitutionsview.h"
|
|
|
|
#include "../kmymoneyglobalsettings.h"
|
|
|
|
#include "../kmymoney2.h"
|
|
|
|
|
|
|
|
KInstitutionsView::KInstitutionsView(TQWidget *parent, const char *name) :
|
|
|
|
KInstitutionsViewDecl(parent,name),
|
|
|
|
m_needReload(false)
|
|
|
|
{
|
|
|
|
m_accountTree->header()->setLabel(0, i18n("Institution/Account"));
|
|
|
|
|
|
|
|
connect(m_accountTree, TQT_SIGNAL(selectObject(const MyMoneyObject&)), this, TQT_SIGNAL(selectObject(const MyMoneyObject&)));
|
|
|
|
connect(m_accountTree, TQT_SIGNAL(openContextMenu(const MyMoneyObject&)), this, TQT_SIGNAL(openContextMenu(const MyMoneyObject&)));
|
|
|
|
connect(m_accountTree, TQT_SIGNAL(valueChanged(void)), this, TQT_SLOT(slotUpdateNetWorth(void)));
|
|
|
|
connect(m_accountTree, TQT_SIGNAL(openObject(const MyMoneyObject&)), this, TQT_SIGNAL(openObject(const MyMoneyObject&)));
|
|
|
|
connect(m_accountTree, TQT_SIGNAL(reparent(const MyMoneyAccount&, const MyMoneyInstitution&)), this, TQT_SIGNAL(reparent(const MyMoneyAccount&, const MyMoneyInstitution&)));
|
|
|
|
|
|
|
|
connect(MyMoneyFile::instance(), TQT_SIGNAL(dataChanged()), this, TQT_SLOT(slotLoadAccounts()));
|
|
|
|
}
|
|
|
|
|
|
|
|
KInstitutionsView::~KInstitutionsView()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void KInstitutionsView::show(void)
|
|
|
|
{
|
|
|
|
if(m_needReload) {
|
|
|
|
loadAccounts();
|
|
|
|
m_needReload = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// don't forget base class implementation
|
|
|
|
KInstitutionsViewDecl::show();
|
|
|
|
|
|
|
|
// if we have a selected account, let the application know about it
|
|
|
|
KMyMoneyAccountTreeBaseItem *item = m_accountTree->selectedItem();
|
|
|
|
if(item) {
|
|
|
|
emit selectObject(item->itemObject());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KInstitutionsView::polish(void)
|
|
|
|
{
|
|
|
|
KInstitutionsViewDecl::polish();
|
|
|
|
m_accountTree->setResizeMode(TQListView::LastColumn);
|
|
|
|
m_accountTree->restoreLayout("Institution View Settings");
|
|
|
|
}
|
|
|
|
|
|
|
|
void KInstitutionsView::slotLoadAccounts(void)
|
|
|
|
{
|
|
|
|
if(isVisible()) {
|
|
|
|
loadAccounts();
|
|
|
|
} else {
|
|
|
|
m_needReload = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KInstitutionsView::loadAccounts(void)
|
|
|
|
{
|
|
|
|
TQMap<TQString, bool> isOpen;
|
|
|
|
|
|
|
|
::timetrace("start load institutions view");
|
|
|
|
// remember the id of the current selected item
|
|
|
|
KMyMoneyAccountTreeBaseItem *item = m_accountTree->selectedItem();
|
|
|
|
TQString selectedItemId = (item) ? item->id() : TQString();
|
|
|
|
|
|
|
|
// keep a map of all 'expanded' accounts
|
|
|
|
TQListViewItemIterator it_lvi(m_accountTree);
|
|
|
|
while(it_lvi.current()) {
|
|
|
|
item = dynamic_cast<KMyMoneyAccountTreeItem*>(it_lvi.current());
|
|
|
|
if(item && item->isOpen()) {
|
|
|
|
isOpen[item->id()] = true;
|
|
|
|
}
|
|
|
|
++it_lvi;
|
|
|
|
}
|
|
|
|
|
|
|
|
// remember the upper left corner of the viewport
|
|
|
|
TQPoint startPoint = m_accountTree->viewportToContents(TQPoint(0, 0));
|
|
|
|
|
|
|
|
// turn off updates to avoid flickering during reload
|
|
|
|
m_accountTree->setUpdatesEnabled(false);
|
|
|
|
|
|
|
|
// clear the current contents and recreate it
|
|
|
|
m_accountTree->clear();
|
|
|
|
m_accountMap.clear();
|
|
|
|
m_securityMap.clear();
|
|
|
|
m_transactionCountMap.clear();
|
|
|
|
|
|
|
|
MyMoneyFile* file = MyMoneyFile::instance();
|
|
|
|
|
|
|
|
TQValueList<MyMoneyAccount> alist;
|
|
|
|
file->accountList(alist);
|
|
|
|
TQValueList<MyMoneyAccount>::const_iterator it_a;
|
|
|
|
for(it_a = alist.begin(); it_a != alist.end(); ++it_a) {
|
|
|
|
m_accountMap[(*it_a).id()] = *it_a;
|
|
|
|
}
|
|
|
|
|
|
|
|
// we need to make sure we show stock accounts
|
|
|
|
// under the right institution (the one of the parent account)
|
|
|
|
TQMap<TQString, MyMoneyAccount>::iterator it_am;
|
|
|
|
for(it_am = m_accountMap.begin(); it_am != m_accountMap.end(); ++it_am) {
|
|
|
|
if((*it_am).isInvest()) {
|
|
|
|
(*it_am).setInstitutionId(m_accountMap[(*it_am).parentAccountId()].institutionId());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQValueList<MyMoneySecurity> slist = file->currencyList();
|
|
|
|
slist += file->securityList();
|
|
|
|
TQValueList<MyMoneySecurity>::const_iterator it_s;
|
|
|
|
for(it_s = slist.begin(); it_s != slist.end(); ++it_s) {
|
|
|
|
m_securityMap[(*it_s).id()] = *it_s;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_transactionCountMap = file->transactionCountMap();
|
|
|
|
|
|
|
|
m_accountTree->setBaseCurrency(file->baseCurrency());
|
|
|
|
|
|
|
|
// create the items
|
|
|
|
try {
|
|
|
|
const MyMoneySecurity& security = file->baseCurrency();
|
|
|
|
m_accountTree->setBaseCurrency(security);
|
|
|
|
|
|
|
|
MyMoneyInstitution none;
|
|
|
|
none.setName(i18n("Accounts with no institution assigned"));
|
|
|
|
KMyMoneyAccountTreeItem* noInstitutionItem = new KMyMoneyAccountTreeItem(m_accountTree, none);
|
|
|
|
noInstitutionItem->setPixmap(0,none.pixmap());
|
|
|
|
loadSubAccounts(noInstitutionItem, TQString());
|
|
|
|
|
|
|
|
// hide it, if unused
|
|
|
|
noInstitutionItem->setVisible(noInstitutionItem->childCount() != 0);
|
|
|
|
|
|
|
|
TQValueList<MyMoneyInstitution> list = file->institutionList();
|
|
|
|
TQValueList<MyMoneyInstitution>::const_iterator it_i;
|
|
|
|
for(it_i = list.begin(); it_i != list.end(); ++it_i) {
|
|
|
|
KMyMoneyAccountTreeItem* item = new KMyMoneyAccountTreeItem(m_accountTree, *it_i);
|
|
|
|
item->setPixmap(0, none.pixmap());
|
|
|
|
loadSubAccounts(item, (*it_i).id());
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch(MyMoneyException *e) {
|
|
|
|
kdDebug(2) << "Problem in institutions view: " << e->what();
|
|
|
|
delete e;
|
|
|
|
}
|
|
|
|
|
|
|
|
// scan through the list of accounts and re-expand those that were
|
|
|
|
// expanded and re-select the one that was probably selected before
|
|
|
|
it_lvi = TQListViewItemIterator(m_accountTree);
|
|
|
|
while(it_lvi.current()) {
|
|
|
|
item = dynamic_cast<KMyMoneyAccountTreeItem*>(it_lvi.current());
|
|
|
|
if(item) {
|
|
|
|
if(item->id() == selectedItemId)
|
|
|
|
m_accountTree->setSelected(item, true);
|
|
|
|
if(isOpen.find(item->id()) != isOpen.end())
|
|
|
|
item->setOpen(true);
|
|
|
|
}
|
|
|
|
++it_lvi;
|
|
|
|
}
|
|
|
|
|
|
|
|
// reposition viewport
|
|
|
|
m_accountTree->setContentsPos(startPoint.x(), startPoint.y());
|
|
|
|
|
|
|
|
// turn updates back on
|
|
|
|
m_accountTree->setUpdatesEnabled(true);
|
|
|
|
m_accountTree->repaintContents();
|
|
|
|
|
|
|
|
::timetrace("done load institutions view");
|
|
|
|
}
|
|
|
|
|
|
|
|
void KInstitutionsView::loadSubAccounts(KMyMoneyAccountTreeItem* parent)
|
|
|
|
{
|
|
|
|
bool showClosedAccounts = kmymoney2->toggleAction("view_show_all_accounts")->isChecked();
|
|
|
|
const MyMoneyAccount& account = dynamic_cast<const MyMoneyAccount&>(parent->itemObject());
|
|
|
|
TQValueList<TQString>::const_iterator it_a;
|
|
|
|
MyMoneyFile* file = MyMoneyFile::instance();
|
|
|
|
for(it_a = account.accountList().begin(); it_a != account.accountList().end(); ++it_a) {
|
|
|
|
MyMoneyAccount acc = m_accountMap[(*it_a)];
|
|
|
|
if(!acc.isInvest())
|
|
|
|
continue;
|
|
|
|
if(acc.isClosed() && !showClosedAccounts)
|
|
|
|
continue;
|
|
|
|
const MyMoneySecurity& security = m_securityMap[acc.currencyId()];
|
|
|
|
TQValueList<MyMoneyPrice> prices;
|
|
|
|
prices += file->price(acc.currencyId(), security.tradingCurrency());
|
|
|
|
if(security.tradingCurrency() != file->baseCurrency().id()) {
|
|
|
|
MyMoneySecurity sec = m_securityMap[security.tradingCurrency()];
|
|
|
|
prices += file->price(sec.id(), file->baseCurrency().id());
|
|
|
|
}
|
|
|
|
KMyMoneyAccountTreeItem* item = new KMyMoneyAccountTreeItem(parent, acc, prices, security);
|
|
|
|
if(acc.id() == m_reconciliationAccount.id())
|
|
|
|
item->setReconciliation(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KInstitutionsView::loadSubAccounts(KMyMoneyAccountTreeItem* parent, const TQString& institutionId)
|
|
|
|
{
|
|
|
|
MyMoneyFile* file = MyMoneyFile::instance();
|
|
|
|
|
|
|
|
TQMap<TQString, MyMoneyAccount>::const_iterator it_a;
|
|
|
|
MyMoneyMoney value;
|
|
|
|
bool showClosedAccounts = kmymoney2->toggleAction("view_show_all_accounts")->isChecked();
|
|
|
|
|
|
|
|
for(it_a = m_accountMap.begin(); it_a != m_accountMap.end(); ++it_a) {
|
|
|
|
const MyMoneyAccount& acc = *it_a;
|
|
|
|
MyMoneyMoney factor(1,1);
|
|
|
|
switch(acc.accountGroup()) {
|
|
|
|
case MyMoneyAccount::Liability:
|
|
|
|
factor = MyMoneyMoney(-1,1);
|
|
|
|
// tricky fall through here
|
|
|
|
|
|
|
|
case MyMoneyAccount::Asset:
|
|
|
|
if(acc.institutionId() == institutionId
|
|
|
|
&& !acc.isInvest()
|
|
|
|
&& (!acc.isClosed() || showClosedAccounts)) {
|
|
|
|
TQValueList<MyMoneyPrice> prices;
|
|
|
|
MyMoneySecurity security = file->baseCurrency();
|
|
|
|
try {
|
|
|
|
if(acc.currencyId() != file->baseCurrency().id()) {
|
|
|
|
security = m_securityMap[acc.currencyId()];
|
|
|
|
prices += file->price(acc.currencyId(), file->baseCurrency().id());
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch(MyMoneyException *e) {
|
|
|
|
kdDebug(2) << __PRETTY_FUNCTION__ << " caught exception while adding " << acc.name() << "[" << acc.id() << "]: " << e->what();
|
|
|
|
delete e;
|
|
|
|
}
|
|
|
|
|
|
|
|
KMyMoneyAccountTreeItem* item = new KMyMoneyAccountTreeItem(parent, acc, prices, security);
|
|
|
|
if(acc.id() == m_reconciliationAccount.id())
|
|
|
|
item->setReconciliation(true);
|
|
|
|
|
|
|
|
if(acc.accountType() == MyMoneyAccount::Investment)
|
|
|
|
loadSubAccounts(item);
|
|
|
|
value += (item->totalValue() * factor);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// the calulated value for the institution is not correct as
|
|
|
|
// it does not take the negative sign for liability accounts
|
|
|
|
// into account. So we correct this here with the value we
|
|
|
|
// have calculated while filling the list
|
|
|
|
parent->adjustTotalValue(-parent->totalValue()); // load a 0
|
|
|
|
parent->adjustTotalValue(value); // now store the new value
|
|
|
|
|
|
|
|
// we need to call slotUpdateNetWorth() here manually, because
|
|
|
|
// KMyMoneyAccountTreeItem::adjustTotalValue() does not send out
|
|
|
|
// the valueChanged() signal
|
|
|
|
slotUpdateNetWorth();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KInstitutionsView::slotUpdateNetWorth(void)
|
|
|
|
{
|
|
|
|
MyMoneyMoney netWorth;
|
|
|
|
|
|
|
|
// calculate by going through the account trees top items
|
|
|
|
// and summing up the total value shown there
|
|
|
|
KMyMoneyAccountTreeItem* item = dynamic_cast<KMyMoneyAccountTreeItem*>(m_accountTree->firstChild());
|
|
|
|
while(item) {
|
|
|
|
netWorth += item->totalValue();
|
|
|
|
item = dynamic_cast<KMyMoneyAccountTreeItem*>(item->nextSibling());
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString s(i18n("Net Worth: "));
|
|
|
|
|
|
|
|
// FIXME figure out how to deal with the approximate
|
|
|
|
// if(!(file->totalValueValid(assetAccount.id()) & file->totalValueValid(liabilityAccount.id())))
|
|
|
|
// s += "~ ";
|
|
|
|
|
|
|
|
s.replace(TQString(" "), TQString(" "));
|
|
|
|
if(netWorth.isNegative()) {
|
|
|
|
s += "<b><font color=\"red\">";
|
|
|
|
}
|
|
|
|
const MyMoneySecurity& sec = MyMoneyFile::instance()->baseCurrency();
|
|
|
|
TQString v(netWorth.formatMoney(sec));
|
|
|
|
s += v.replace(TQString(" "), TQString(" "));
|
|
|
|
if(netWorth.isNegative()) {
|
|
|
|
s += "</font></b>";
|
|
|
|
}
|
|
|
|
|
|
|
|
m_totalProfitsLabel->setFont(KMyMoneyGlobalSettings::listCellFont());
|
|
|
|
m_totalProfitsLabel->setText(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KInstitutionsView::slotReconcileAccount(const MyMoneyAccount& acc, const TQDate& reconciliationDate, const MyMoneyMoney& endingBalance)
|
|
|
|
{
|
|
|
|
Q_UNUSED(reconciliationDate);
|
|
|
|
Q_UNUSED(endingBalance);
|
|
|
|
|
|
|
|
// scan through the list of accounts and mark all non
|
|
|
|
// expanded and re-select the one that was probably selected before
|
|
|
|
TQListViewItemIterator it_lvi(m_accountTree);
|
|
|
|
KMyMoneyAccountTreeItem* item;
|
|
|
|
while(it_lvi.current()) {
|
|
|
|
item = dynamic_cast<KMyMoneyAccountTreeItem*>(it_lvi.current());
|
|
|
|
if(item) {
|
|
|
|
item->setReconciliation(false);
|
|
|
|
}
|
|
|
|
++it_lvi;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_reconciliationAccount = acc;
|
|
|
|
if(!acc.id().isEmpty()) {
|
|
|
|
it_lvi = TQListViewItemIterator(m_accountTree);
|
|
|
|
while(it_lvi.current()) {
|
|
|
|
item = dynamic_cast<KMyMoneyAccountTreeItem*>(it_lvi.current());
|
|
|
|
if(item && item->itemObject().id() == acc.id()) {
|
|
|
|
item->setReconciliation(true);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++it_lvi;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#include "kinstitutionsview.moc"
|