You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kmymoney/kmymoney2/widgets/kmymoneyaccounttreebase.cpp

826 lines
25 KiB

/***************************************************************************
kmymoneyaccounttree.cpp - description
-------------------
begin : Sat Jan 1 2005
copyright : (C) 2005 by Thomas Baumgart
email : Thomas Baumgart <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 <tqpoint.h>
#include <tqevent.h>
#include <tqdragobject.h>
#include <tqtimer.h>
#include <tqcursor.h>
#include <tqheader.h>
#include <tqpainter.h>
#include <tqpixmap.h>
#include <tqstyle.h>
// ----------------------------------------------------------------------------
// KDE Includes
#include <kmessagebox.h>
#include <klocale.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <kstandarddirs.h>
// ----------------------------------------------------------------------------
// Project Includes
#include <kmymoney/mymoneyfile.h>
#include <kmymoney/kmymoneyaccounttree.h>
#include <kmymoney/kmymoneyglobalsettings.h>
#include <kmymoney/kmymoneyutils.h>
KMyMoneyAccountTreeBase::KMyMoneyAccountTreeBase(TQWidget* parent, const char* name) :
KListView(parent, name),
m_accountConnections(false),
m_institutionConnections(false),
m_queuedSort(0)
{
setRootIsDecorated(true);
setAllColumnsShowFocus(true);
m_nameColumn = addColumn(i18n("Account"));
setColumnWidthMode(m_nameColumn, TQListView::Manual);
m_typeColumn = -1;
m_balanceColumn = -1;
m_valueColumn = -1;
setMultiSelection(false);
setResizeMode(TQListView::LastColumn);
setShowSortIndicator(true);
setSorting(0);
header()->setResizeEnabled(true);
setDragEnabled(false);
setAcceptDrops(false);
setItemsMovable(false);
setDropVisualizer(false);
setDropHighlighter(true);
// setup a default
m_baseCurrency.setSmallestAccountFraction(100);
m_baseCurrency.setSmallestCashFraction(100);
connect(this, TQT_SIGNAL(dropped(TQDropEvent*,TQListViewItem*,TQListViewItem*)), this, TQT_SLOT(slotObjectDropped(TQDropEvent*,TQListViewItem*,TQListViewItem*)));
connect(this, TQT_SIGNAL(selectionChanged(TQListViewItem*)), this, TQT_SLOT(slotSelectObject(TQListViewItem*)));
connect(this, TQT_SIGNAL(contextMenu(KListView*, TQListViewItem* , const TQPoint&)), this, TQT_SLOT(slotOpenContextMenu(KListView*, TQListViewItem*, const TQPoint&)));
connect(this, TQT_SIGNAL(doubleClicked(TQListViewItem*,const TQPoint&,int)), this, TQT_SLOT(slotOpenObject(TQListViewItem*)));
// drag and drop timer connections
connect( &m_autoopenTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotOpenFolder() ) );
connect( &m_autoscrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotAutoScroll() ) );
}
KMyMoneyAccountTreeBase::~KMyMoneyAccountTreeBase()
{
if (!m_configGroup.isEmpty())
saveLayout(TDEGlobal::config(), m_configGroup);
}
void KMyMoneyAccountTreeBase::restoreLayout(const TQString& group)
{
if (!m_configGroup.isEmpty())
return; // already done
// make sure to use the previous settings. If no settings are found
// we use equal distribution of all fields as an initial setting
// TODO this only makes the first column invisible if settings exist setColumnWidth(0, 0);
m_configGroup = group;
KListView::restoreLayout(TDEGlobal::config(), m_configGroup);
}
void KMyMoneyAccountTreeBase::showType(void)
{
m_typeColumn = addColumn(i18n("Type"));
setColumnWidthMode(m_typeColumn, TQListView::Manual);
setColumnAlignment(m_typeColumn, TQt::AlignLeft);
}
void KMyMoneyAccountTreeBase::showValue(void)
{
m_balanceColumn = addColumn(i18n("Total Balance"));
setColumnWidthMode(m_balanceColumn, TQListView::Manual);
setColumnAlignment(m_balanceColumn, TQt::AlignRight);
m_valueColumn = addColumn(i18n("Total Value"));
setColumnWidthMode(m_valueColumn, TQListView::Manual);
setColumnAlignment(m_valueColumn, TQt::AlignRight);
}
void KMyMoneyAccountTreeBase::connectNotify(const char * /* s */)
{
// update drag and drop settings
m_accountConnections = (receivers(TQT_SIGNAL(reparent(const MyMoneyAccount&, const MyMoneyAccount&))) != 0);
m_institutionConnections = (receivers(TQT_SIGNAL(reparent(const MyMoneyAccount&, const MyMoneyInstitution&))) != 0);
setDragEnabled(m_accountConnections | m_institutionConnections);
setAcceptDrops(m_accountConnections | m_institutionConnections);
}
void KMyMoneyAccountTreeBase::disconnectNotify(const char * /* s */)
{
// update drag and drop settings
m_accountConnections = (receivers(TQT_SIGNAL(reparent(const MyMoneyAccount&, const MyMoneyAccount&))) != 0);
m_institutionConnections = (receivers(TQT_SIGNAL(reparent(const MyMoneyAccount&, const MyMoneyInstitution&))) != 0);
setDragEnabled(m_accountConnections | m_institutionConnections);
setAcceptDrops(m_accountConnections | m_institutionConnections);
}
void KMyMoneyAccountTreeBase::setSectionHeader(const TQString& txt)
{
header()->setLabel(nameColumn(), txt);
}
KMyMoneyAccountTreeBaseItem* KMyMoneyAccountTreeBase::selectedItem(void) const
{
return dynamic_cast<KMyMoneyAccountTreeBaseItem *>(KListView::selectedItem());
}
const KMyMoneyAccountTreeBaseItem* KMyMoneyAccountTreeBase::findItem(const TQString& id) const
{
// tried to use a TQListViewItemIterator but that does not fit
// with the constness of this method. Arghhh.
TQListViewItem* p = firstChild();
while(p) {
// item found, check for the id
KMyMoneyAccountTreeBaseItem* item = dynamic_cast<KMyMoneyAccountTreeBaseItem*>(p);
if(item && item->id() == id)
break;
// item did not match, search the next one
TQListViewItem* next = p->firstChild();
if(!next) {
while((next = p->nextSibling()) == 0) {
p = p->parent();
if(!p)
break;
}
}
p = next;
}
return dynamic_cast<KMyMoneyAccountTreeBaseItem*>(p);
}
bool KMyMoneyAccountTreeBase::dropAccountOnAccount(const MyMoneyAccount& accFrom, const MyMoneyAccount& accTo) const
{
bool rc = false;
// it does not make sense to reparent an account to oneself
// or to reparent it to it's current parent
if(accTo.id() != accFrom.id()
&& accFrom.parentAccountId() != accTo.id()) {
// Moving within a group is generally ok
rc = accTo.accountGroup() == accFrom.accountGroup();
// now check for exceptions
if(rc) {
if(accTo.accountType() == MyMoneyAccount::Investment
&& !accFrom.isInvest())
rc = false;
else if(accFrom.isInvest()
&& accTo.accountType() != MyMoneyAccount::Investment)
rc = false;
} else {
if(accFrom.accountGroup() == MyMoneyAccount::Income
&& accTo.accountGroup() == MyMoneyAccount::Expense)
rc = true;
if(accFrom.accountGroup() == MyMoneyAccount::Expense
&& accTo.accountGroup() == MyMoneyAccount::Income)
rc = true;
}
// if it's generally ok to drop here, make sure that
// the accTo does not have a child with the same name
const KMyMoneyAccountTreeBaseItem* to = findItem(accTo.id());
if(to) {
to = dynamic_cast<KMyMoneyAccountTreeBaseItem*> (to->firstChild());
while(to && rc) {
if(to->isAccount()) {
const MyMoneyAccount& acc = dynamic_cast<const MyMoneyAccount&>(to->itemObject());
if(acc.name() == accFrom.name())
rc = false;
}
to = dynamic_cast<KMyMoneyAccountTreeBaseItem*> (to->nextSibling());
}
}
}
return rc;
}
bool KMyMoneyAccountTreeBase::acceptDrag(TQDropEvent* event) const
{
bool rc;
if((rc = (acceptDrops()) && (event->source() == viewport()))) {
rc = false;
KMyMoneyAccountTreeBaseItem* to = dynamic_cast<KMyMoneyAccountTreeBaseItem*>(itemAt( contentsToViewport(event->pos()) ));
TQString fromId(event->encodedData("text/plain"));
const KMyMoneyAccountTreeBaseItem* from = findItem(fromId);
// we can only move accounts around
if(!from->isAccount())
from = 0;
if(to && from && !to->isChildOf(from)) {
const MyMoneyAccount& accFrom = dynamic_cast<const MyMoneyAccount&>(from->itemObject());
if(to->isAccount() && m_accountConnections) {
const MyMoneyAccount& accTo = dynamic_cast<const MyMoneyAccount&>(to->itemObject());
rc = dropAccountOnAccount(accFrom, accTo);
} else if(to->isInstitution() && m_institutionConnections) {
// Moving a non-stock account to an institution is ok
if(!accFrom.isInvest())
rc = true;
}
}
}
return rc;
}
void KMyMoneyAccountTreeBase::startDrag(void)
{
TQListViewItem* item = currentItem();
KMyMoneyAccountTreeBaseItem* p = dynamic_cast<KMyMoneyAccountTreeBaseItem *>(item);
if(!p)
return;
if(p->isAccount()) {
TQTextDrag* drag = new TQTextDrag(p->id(), viewport());
drag->setSubtype("plain");
// use the icon that is attached to the item to be dragged
if (p->pixmap(0)) {
TQPixmap pixmap(*p->pixmap(0));
TQPoint hotspot( pixmap.width() / 2, pixmap.height() / 2 );
drag->setPixmap(pixmap, hotspot);
}
if (drag->dragMove() && drag->target() != viewport())
emit moved();
}
return;
}
void KMyMoneyAccountTreeBase::slotObjectDropped(TQDropEvent* event, TQListViewItem* /* parent */, TQListViewItem* /* after */)
{
m_autoopenTimer.stop();
slotStopAutoScroll();
if(dropHighlighter())
cleanItemHighlighter();
KMyMoneyAccountTreeBaseItem* newParent = dynamic_cast<KMyMoneyAccountTreeBaseItem*>(m_dropItem);
if(newParent) {
TQString fromId(event->encodedData("text/plain"));
const KMyMoneyAccountTreeBaseItem* from = findItem(fromId);
// we can only move accounts around
if(!from->isAccount())
from = 0;
if(from) {
const MyMoneyAccount& accFrom = dynamic_cast<const MyMoneyAccount&>(from->itemObject());
if(newParent->isAccount()) {
const MyMoneyAccount& accTo = dynamic_cast<const MyMoneyAccount&>(newParent->itemObject());
if(dropAccountOnAccount(accFrom, accTo)) {
emit reparent(accFrom, accTo);
}
} else if(newParent->isInstitution()) {
if(!accFrom.isInvest()) {
const MyMoneyInstitution& institution = dynamic_cast<const MyMoneyInstitution&>(newParent->itemObject());
emit reparent(accFrom, institution);
}
}
}
}
}
void KMyMoneyAccountTreeBase::slotSelectObject(TQListViewItem* i)
{
emit selectObject(MyMoneyInstitution());
emit selectObject(MyMoneyAccount());
KMyMoneyAccountTreeBaseItem* item = dynamic_cast<KMyMoneyAccountTreeBaseItem*>(i);
if(item != 0) {
emit selectObject(item->itemObject());
}
}
void KMyMoneyAccountTreeBase::slotOpenContextMenu(KListView* lv, TQListViewItem* i, const TQPoint&)
{
Q_UNUSED(lv);
KMyMoneyAccountTreeBaseItem* item = dynamic_cast<KMyMoneyAccountTreeBaseItem *>(i);
if(item) {
emit selectObject(item->itemObject());
// Create a copy of the item since the original might be destroyed
// during processing of this signal.
if(item->isInstitution()) {
MyMoneyInstitution institution = dynamic_cast<const MyMoneyInstitution&>(item->itemObject());
emit openContextMenu(institution);
} else {
MyMoneyAccount account = dynamic_cast<const MyMoneyAccount&>(item->itemObject());
emit openContextMenu(account);
}
}
}
void KMyMoneyAccountTreeBase::slotOpenObject(TQListViewItem* i)
{
KMyMoneyAccountTreeBaseItem* item = dynamic_cast<KMyMoneyAccountTreeBaseItem *>(i);
if(item) {
// Create a copy of the item since the original might be destroyed
// during processing of this signal.
if(item->isAccount()) {
MyMoneyAccount acc = dynamic_cast<const MyMoneyAccount&>(item->itemObject());
emit openObject(acc);
} else if(item->isInstitution()) {
MyMoneyInstitution inst = dynamic_cast<const MyMoneyInstitution&>(item->itemObject());
emit openObject(inst);
}
}
}
/* drag and drop support inspired partially from KMail */
/* --------------------------------------------------- */
static const int autoscrollMargin = 16;
static const int initialScrollTime = 30;
static const int initialScrollAccel = 5;
static const int autoopenTime = 750;
void KMyMoneyAccountTreeBase::slotOpenFolder(void)
{
m_autoopenTimer.stop();
if ( m_dropItem && !m_dropItem->isOpen() ) {
m_dropItem->setOpen( TRUE );
m_dropItem->repaint();
}
}
void KMyMoneyAccountTreeBase::slotStartAutoScroll(void)
{
if ( !m_autoscrollTimer.isActive() ) {
m_autoscrollTime = initialScrollTime;
m_autoscrollAccel = initialScrollAccel;
m_autoscrollTimer.start( m_autoscrollTime );
}
}
void KMyMoneyAccountTreeBase::slotStopAutoScroll(void)
{
m_autoscrollTimer.stop();
}
void KMyMoneyAccountTreeBase::slotAutoScroll(void)
{
// don't show a highlighter during scrolling
cleanItemHighlighter();
TQPoint p = viewport()->mapFromGlobal( TQCursor::pos() );
if ( m_autoscrollAccel-- <= 0 && m_autoscrollTime ) {
m_autoscrollAccel = initialScrollAccel;
m_autoscrollTime--;
m_autoscrollTimer.start( m_autoscrollTime );
}
int l = TQMAX(1,(initialScrollTime-m_autoscrollTime));
int dx=0,dy=0;
if ( p.y() < autoscrollMargin ) {
dy = -l;
} else if ( p.y() > visibleHeight()-autoscrollMargin ) {
dy = +l;
}
if ( p.x() < autoscrollMargin ) {
dx = -l;
} else if ( p.x() > visibleWidth()-autoscrollMargin ) {
dx = +l;
}
if ( dx || dy ) {
scrollBy(dx, dy);
} else {
slotStopAutoScroll();
}
}
void KMyMoneyAccountTreeBase::contentsDragMoveEvent(TQDragMoveEvent* e)
{
TQPoint vp = contentsToViewport(e->pos());
TQRect inside_margin((contentsX() > 0) ? autoscrollMargin : 0,
(contentsY() > 0) ? autoscrollMargin : 0,
visibleWidth() - ((contentsX() + visibleWidth() < contentsWidth())
? autoscrollMargin*2 : 0),
visibleHeight() - ((contentsY() + visibleHeight() < contentsHeight())
? autoscrollMargin*2 : 0));
bool accepted = false;
TQListViewItem *i = itemAt( vp );
if ( i ) {
accepted = acceptDrag(e);
if(accepted && !m_autoscrollTimer.isActive()) {
if (dropHighlighter()) {
TQRect tmpRect = drawItemHighlighter(0, i);
if (tmpRect != m_lastDropHighlighter) {
cleanItemHighlighter();
m_lastDropHighlighter = tmpRect;
viewport()->repaint(tmpRect);
}
}
}
if ( !inside_margin.contains(vp) ) {
slotStartAutoScroll();
e->accept(TQRect(0,0,0,0)); // Keep sending move events
m_autoopenTimer.stop();
} else {
if(accepted)
e->accept();
else
e->ignore();
if ( i != m_dropItem ) {
m_autoopenTimer.stop();
m_dropItem = i;
m_autoopenTimer.start( autoopenTime );
}
}
if ( accepted ) {
switch ( e->action() ) {
case TQDropEvent::Copy:
case TQDropEvent::Link:
break;
case TQDropEvent::Move:
e->acceptAction();
break;
default:
break;
}
}
} else {
e->ignore();
m_autoopenTimer.stop();
m_dropItem = 0;
}
if(!accepted && dropHighlighter())
cleanItemHighlighter();
}
void KMyMoneyAccountTreeBase::cleanItemHighlighter(void)
{
if(m_lastDropHighlighter.isValid()) {
TQRect rect=m_lastDropHighlighter;
m_lastDropHighlighter = TQRect();
// make sure, we repaint a bit more. that's important during
// autoscroll. if we don't do that, parts of the highlighter
// do not get removed
rect.moveBy(-1, -1);
rect.setSize(rect.size() + TQSize(2,2));
viewport()->repaint(rect, true);
}
}
void KMyMoneyAccountTreeBase::viewportPaintEvent(TQPaintEvent* e)
{
TQListView::viewportPaintEvent(e);
if (m_lastDropHighlighter.isValid() && e->rect().intersects(m_lastDropHighlighter)) {
TQPainter painter(viewport());
// This is where we actually draw the drop-highlighter
style().tqdrawPrimitive(TQStyle::PE_FocusRect, &painter, m_lastDropHighlighter, colorGroup(),
TQStyle::Style_FocusAtBorder);
}
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
const MyMoneyObject& KMyMoneyAccountTreeBaseItem::itemObject(void) const
{
if(m_type == Institution)
return m_institution;
return m_account;
}
KMyMoneyAccountTreeBaseItem::KMyMoneyAccountTreeBaseItem(KListView *parent, const MyMoneyInstitution& institution) :
KListViewItem(parent),
m_totalValue(MyMoneyMoney(0)),
m_negative(false),
m_institution(institution),
m_type(Institution)
{
setName();
}
KMyMoneyAccountTreeBaseItem::KMyMoneyAccountTreeBaseItem(KListView *parent, const MyMoneyAccount& account, const MyMoneySecurity& security, const TQString& name) :
KListViewItem(parent),
m_security(security),
m_totalValue(MyMoneyMoney(0)),
m_account(account),
m_negative(false),
m_type(Account)
{
if(!name.isEmpty()) {
// we do not want to modify the original account
MyMoneyAccount acc(account);
acc.setName(name);
m_account = acc;
}
setName();
}
KMyMoneyAccountTreeBaseItem::KMyMoneyAccountTreeBaseItem(KMyMoneyAccountTreeBaseItem *parent, const MyMoneyAccount& account, const TQValueList<MyMoneyPrice>& price, const MyMoneySecurity& security) :
KListViewItem(parent),
m_price(price),
m_security(security),
m_totalValue(MyMoneyMoney(0)),
m_account(account),
m_negative(false),
m_type(Account)
{
setName();
}
KMyMoneyAccountTreeBaseItem::~KMyMoneyAccountTreeBaseItem()
{
}
const TQString& KMyMoneyAccountTreeBaseItem::id(void) const
{
if(m_type == Institution)
return m_institution.id();
return m_account.id();
}
bool KMyMoneyAccountTreeBaseItem::isChildOf(const TQListViewItem* const item) const
{
TQListViewItem *p = parent();
while(p && p != item) {
p = p->parent();
}
return (p != 0);
}
MyMoneyMoney KMyMoneyAccountTreeBaseItem::value() const
{
// calculate the new value by running down the price list
MyMoneyMoney result = balance();
TQValueList<MyMoneyPrice>::const_iterator it_p;
TQString security = m_security.id();
for(it_p = m_price.begin(); it_p != m_price.end(); ++it_p) {
result = (result * (MyMoneyMoney(1,1) / (*it_p).rate(security))).convert(MyMoneyMoney::precToDenom(KMyMoneyGlobalSettings::pricePrecision()));
if((*it_p).from() == security)
security = (*it_p).to();
else
security = (*it_p).from();
}
if (listView())
result = result.convert(listView()->baseCurrency().smallestAccountFraction());
return result;
}
void KMyMoneyAccountTreeBaseItem::setName()
{
KMyMoneyAccountTreeBase* lv = dynamic_cast<KMyMoneyAccountTreeBase*>(listView());
if (!lv)
return;
if (isInstitution()) {
setPixmap(lv->nameColumn(), m_institution.pixmap());
setText(lv->nameColumn(), m_institution.name());
} else {
setPixmap(lv->nameColumn(), m_account.accountPixmap(false, 22));
setText(lv->nameColumn(), m_account.name());
#ifndef KMM_DESIGNER
if(lv->typeColumn()>=0 && !MyMoneyFile::instance()->isStandardAccount(m_account.id()))
setText(lv->typeColumn(), KMyMoneyUtils::accountTypeToString(m_account.accountType()));
#endif
}
}
void KMyMoneyAccountTreeBaseItem::fillColumns()
{
KMyMoneyAccountTreeBase* lv = dynamic_cast<KMyMoneyAccountTreeBase*>(listView());
if (!lv)
return;
if (lv->valueColumn()<0)
return;
// show the top accounts always in total value
if((isOpen() || m_account.accountList().count() == 0) && parent()) {
// only show the balance, if its a different security/currency
if(m_security.id() != listView()->baseCurrency().id()) {
setText(lv->balanceColumn(), balance().formatMoney(m_security));
}
setText(lv->valueColumn(), m_value.formatMoney(listView()->baseCurrency()) + " ");
} else {
setText(lv->balanceColumn(), " ");
if(parent())
setText(lv->valueColumn(), m_totalValue.formatMoney(listView()->baseCurrency()) + " ");
else
setText(lv->valueColumn(), m_totalValue.formatMoney(listView()->baseCurrency()));
}
}
void KMyMoneyAccountTreeBaseItem::updateAccount(bool forceTotalUpdate)
{
MyMoneyMoney oldValue = m_value;
m_value = value();
fillColumns();
// check if we need to tell upstream account objects in the tree
// that the value has changed
if(oldValue != m_value || forceTotalUpdate) {
adjustTotalValue(m_value - oldValue);
if (listView())
listView()->emitValueChanged();
}
}
void KMyMoneyAccountTreeBaseItem::setOpen(bool open)
{
if (open == isOpen())
return;
KListViewItem::setOpen(open);
fillColumns();
if(listView())
listView()->queueSort();
}
void KMyMoneyAccountTreeBaseItem::adjustTotalValue(const MyMoneyMoney& diff)
{
m_totalValue += diff;
// if the entry has no children,
// or it is the top entry
// or it is currently not open
// we need to display the value of it
KMyMoneyAccountTreeBase* lv = dynamic_cast<KMyMoneyAccountTreeBase*>(listView());
if(!lv)
return;
if(!firstChild() || !parent() || (!isOpen() && firstChild())) {
if(firstChild())
setText(lv->balanceColumn(), " ");
if(parent())
setText(lv->valueColumn(), m_totalValue.formatMoney(listView()->baseCurrency()) + " ");
else
setText(lv->valueColumn(), m_totalValue.formatMoney(listView()->baseCurrency()));
}
// now make sure, the upstream accounts also get notified about the value change
KMyMoneyAccountTreeBaseItem* p = dynamic_cast<KMyMoneyAccountTreeBaseItem*>(parent());
if(p != 0) {
p->adjustTotalValue(diff);
}
}
int KMyMoneyAccountTreeBaseItem::compare(TQListViewItem* i, int col, bool ascending) const
{
KMyMoneyAccountTreeBaseItem* item = dynamic_cast<KMyMoneyAccountTreeBaseItem*>(i);
// do special sorting only if
// a) name
// b) account
// c) and different group
// d) value column
// in all other cases use the standard sorting
KMyMoneyAccountTreeBase* lv = dynamic_cast<KMyMoneyAccountTreeBase*>(listView());
if(lv && item) {
if (col == lv->nameColumn()) {
if(m_account.accountGroup() != item->m_account.accountGroup())
return (m_account.accountGroup() - item->m_account.accountGroup());
} else if (col == lv->balanceColumn() || col == lv->valueColumn()) {
MyMoneyMoney result = MyMoneyMoney(text(col)) - MyMoneyMoney(item->text(col));
if(result.isNegative())
return -1;
if(result.isZero())
return 0;
return 1;
}
}
// do standard sorting here
return KListViewItem::compare(i, col, ascending);
}
void KMyMoneyAccountTreeBaseItem::paintCell(TQPainter *p, const TQColorGroup & cg, int column, int width, int align)
{
TQColorGroup cg2(cg);
//set item background
if(isAlternate())
cg2.setColor(TQColorGroup::Base, KMyMoneyGlobalSettings::listColor());
else
cg2.setColor(TQColorGroup::Base, KMyMoneyGlobalSettings::listBGColor());
#ifndef KMM_DESIGNER
// display base accounts in bold
TQFont font = KMyMoneyGlobalSettings::listCellFont();
if(!parent())
font.setBold(true);
// strike out closed accounts
if(m_account.isClosed())
font.setStrikeOut(true);
p->setFont(font);
#endif
//set text color
TQColor textColour;
if(m_negative == true) {
textColour = KMyMoneyGlobalSettings::listNegativeValueColor(); //if the item is marked is marked as negative, all columns will be painted negative
} else {
textColour = m_columnsColor[column]; //otherwise, respect the color for each column
}
cg2.setColor(TQColorGroup::Text, textColour);
TQListViewItem::paintCell(p, cg2, column, width, align);
}
void KMyMoneyAccountTreeBase::expandCollapseAll(bool expand)
{
TQListViewItemIterator it(this);
TQListViewItem* p;
while((p = it.current()) != 0) {
p->setOpen(expand);
++it;
}
}
void KMyMoneyAccountTreeBase::slotExpandAll(void)
{
expandCollapseAll(true);
}
void KMyMoneyAccountTreeBase::slotCollapseAll(void)
{
expandCollapseAll(false);
}
void KMyMoneyAccountTreeBase::queueSort(void)
{
if (sortColumn() == balanceColumn() || sortColumn() == valueColumn()) {
++m_queuedSort;
TQTimer::singleShot(100, this, TQT_SLOT(slotActivateSort()));
}
}
void KMyMoneyAccountTreeBase::slotActivateSort(void)
{
--m_queuedSort;
if(!m_queuedSort)
KListView::sort();
}
void KMyMoneyAccountTreeBaseItem::setNegative(bool isNegative)
{
m_negative = isNegative;
}
void KMyMoneyAccountTreeBaseItem::setText( int column, const TQString &text, const bool &negative)
{
//if negative set the map to negative color according to KMyMoneySettings
if(negative) {
m_columnsColor[column] = KMyMoneyGlobalSettings::listNegativeValueColor();
} else {
m_columnsColor[column] = TQColorGroup::Text;
}
KListViewItem::setText(column, text);
}
#include "kmymoneyaccounttreebase.moc"
// vim:cin:si:ai:et:ts=2:sw=2: