Logo Search packages:      
Sourcecode: qbankmanager version File versions  Download package

transactionlist.cpp

/***************************************************************************
 $RCSfile: transactionlist.cpp,v $
                             -------------------
    cvs         : $Id: transactionlist.cpp,v 1.17 2005/08/31 06:09:39 aquamaniac Exp $
    begin       : Mon Mar 01 2004
    copyright   : (C) 2004 by Martin Preuss
    email       : martin@libchipcard.de

 ***************************************************************************
 *          Please see toplevel file COPYING for license details           *
 ***************************************************************************/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif


#include "transactionlist.h"
#include "payee.h"
#include "category.h"
#include "kbanking.h"

#include <assert.h>
#include <qstring.h>
#include <qpainter.h>
#include <qdatetime.h>
#include <qheader.h>
#include <qprogressdialog.h>
#include <qapplication.h>

#include <gwenhywfar/debug.h>


#define TRANSACTIONLIST_MAXVALUE ((double)(200000000.00))



TransactionListViewItem::TransactionListViewItem(TransactionListView *parent,
                                                 RefPointer<Transaction> t)
:QListViewItem(parent)
,_needUpdate(false)
,_transaction(t){
  TransactionListView *lv;
  int i;

  assert(parent);
  for (i=0; i<TRANSACTION_LISTVIEW_COLUMNS; i++) {
    _cell[i]=0;
  }
  lv=dynamic_cast<TransactionListView*>(listView());
  if (lv)
    _populate(!lv->isShortList());
  else
    _populate(true);
}



TransactionListViewItem::TransactionListViewItem(const TransactionListViewItem &item)
:QListViewItem(item)
,_needUpdate(false) {
  int i;

  for (i=0; i<TRANSACTION_LISTVIEW_COLUMNS; i++) {
    _cell[i]=0;
  }
  _transaction=item._transaction;
}



TransactionListViewItem::TransactionListViewItem(TransactionListView *parent,
                                                 QListViewItem *after,
                                                 RefPointer<Transaction> t)
:QListViewItem(parent, after)
,_needUpdate(false)
,_transaction(t){
  TransactionListView *lv;
  int i;

  for (i=0; i<TRANSACTION_LISTVIEW_COLUMNS; i++) {
    _cell[i]=0;
  }
  lv=dynamic_cast<TransactionListView*>(listView());
  if (lv)
    _populate(!lv->isShortList());
  else
    _populate(true);
}



TransactionListViewItem::~TransactionListViewItem(){
  int i;

  for (i=0; i<TRANSACTION_LISTVIEW_COLUMNS; i++) {
    delete _cell[i];
    _cell[i]=0;
  }
}



void TransactionListViewItem::setColour(const QString &c){
  _colour=c.latin1();
  repaint();
}



RefPointer<Transaction> TransactionListViewItem::getTransaction(){
  return _transaction;
}



void TransactionListViewItem::redrawItem(bool sel) {
  TransactionListView *tv;

  tv=dynamic_cast<TransactionListView*>(listView());
  assert(tv);
  if (tv->isModifying())
    _needUpdate=true;
  else {
    _needUpdate=false;
    _populate(sel);
    setup();
    repaint();
  }
}



bool TransactionListViewItem::needUpdate() {
  return _needUpdate;
}



void TransactionListViewItem::_populate(bool isCurrent) {
  QString tmp;
  int i;
  const std::list<std::string> sl;
  std::list<std::string>::const_iterator it;
  int ht;
  const GWEN_TIME *ti;
  const AB_VALUE *v;
  std::string pid;
  std::string cid;
  QString pname;
  QString cname;
  TransactionListView *tv;

  tv=dynamic_cast<TransactionListView*>(listView());
  assert(tv);
  if (tv->isModifying())
    return;

  for (i=0; i<TRANSACTION_LISTVIEW_COLUMNS; i++) {
    delete _cell[i];
    _cell[i]=0;
  }

  i=0;
  ht=0;

  // date
  tmp="<qt>";
  ti=_transaction.ref().getDate();
  if (!ti)
    ti=_transaction.ref().getValutaDate();
  if (ti) {
    int year, month, day;

    if (!GWEN_Time_GetBrokenDownDate(ti, &day, &month, &year)) {
      QDate t;

      t=QDate(year, month+1, day);
      tmp+=t.toString();
    }
  }
  tmp+="</qt>";
  _cell[i]=new QSimpleRichText(tmp, listView()->font());
  _cell[i]->setWidth(listView()->columnWidth(i)-(2*listView()->itemMargin()));
  ht=(ht<_cell[i]->height())?_cell[i]->height():ht;
  i++;

  // institute
  tmp="<qt>";
  tmp+=QString::fromUtf8(_transaction.ref().getRemoteBankCode().c_str());
  tmp+="</qt>";
  _cell[i]=new QSimpleRichText(tmp, listView()->font());
  _cell[i]->setWidth(listView()->columnWidth(i)-(2*listView()->itemMargin()));
  ht=(ht<_cell[i]->height())?_cell[i]->height():ht;
  i++;

  // account
  tmp="<qt>";
  tmp+=QString::fromUtf8(_transaction.ref().getRemoteAccountNumber().c_str());
  tmp+="</qt>";
  _cell[i]=new QSimpleRichText(tmp, listView()->font());
  _cell[i]->setWidth(listView()->columnWidth(i)-(2*listView()->itemMargin()));
  ht=(ht<_cell[i]->height())?_cell[i]->height():ht;
  i++;

  tmp="<qt>";
  if (isCurrent) {
    // other name
    for (it=_transaction.ref().getRemoteName().begin();
       it!=_transaction.ref().getRemoteName().end();
       it++) {
      tmp+=QString::fromUtf8((*it).c_str());
      tmp+="<br>";
    } // for

    // description
    for (it=_transaction.ref().getPurpose().begin();
       it!=_transaction.ref().getPurpose().end();
       it++) {
      tmp+="<br>";
      tmp+=QString::fromUtf8((*it).c_str());
    } // for
  }
  else {
    // other name
    if (!_transaction.ref().getRemoteName().empty()) {
      tmp+=QString::fromUtf8(_transaction.ref().getRemoteName().front().c_str());
      tmp+="<br>";
    }
    else if (!_transaction.ref().getPurpose().empty()) {
      tmp+=QString::fromUtf8(_transaction.ref().getPurpose().front().c_str());
      tmp+="<br>";
    }
    else {
      tmp="<br>";
    }
  }
  tmp+="</qt>";
  _cell[i]=new QSimpleRichText(tmp, listView()->font());
  _cell[i]->setWidth(listView()->columnWidth(i)-(2*listView()->itemMargin()));
  ht=(ht<_cell[i]->height())?_cell[i]->height():ht;
  i++;

  // type
  tmp="<qt>";
  tmp+=QString::fromUtf8(_transaction.ref().getTransactionText().c_str());
  tmp+=" (";
  tmp+=QString::number(_transaction.ref().getTransactionCode());
  tmp+=")";
  tmp+="</qt>";
  _cell[i]=new QSimpleRichText(tmp, listView()->font());
  _cell[i]->setWidth(listView()->columnWidth(i)-(2*listView()->itemMargin()));
  ht=(ht<_cell[i]->height())?_cell[i]->height():ht;
  i++;

  // value
  tmp="<qt> <p align=right>";
  v=_transaction.ref().getValue();
  if (v) {
    if (AB_Value_GetValue(v)>0)
      tmp+="<font color=\"dark green\">";
    else
      tmp+="<font color=red>";
    tmp+=QString::number(AB_Value_GetValue(v), 'f', 2);
    tmp+=" ";
    tmp+=QString::fromUtf8(AB_Value_GetCurrency(v));
    tmp+="</font>";
  }
  tmp+="</p></qt>";
  _cell[i]=new QSimpleRichText(tmp, listView()->font());
  _cell[i]->setWidth(listView()->columnWidth(i)-(2*listView()->itemMargin()));
  ht=(ht<_cell[i]->height())?_cell[i]->height():ht;
  i++;

  // payee and category, payee here
  pid=_transaction.ref().getPayee();
  pname==QWidget::tr("unknown");
  if (!pid.empty()) {
    TransactionListView *lv=dynamic_cast<TransactionListView*>(listView());
    if (lv) {
      KBanking *app=lv->app();
      if (app) {
        Payee *p;

        p=app->findPayeeById(pid.c_str());
        if (p)
          pname=QString::fromUtf8(p->name().c_str());
      }
    }
  }

  // category
  cid=_transaction.ref().getCategory();
  cname==QWidget::tr("unknown");
  if (!cid.empty()) {
    TransactionListView *lv=dynamic_cast<TransactionListView*>(listView());
    if (lv) {
      KBanking *app=lv->app();
      if (app) {
        Category *cat;

        cat=app->findCategoryById(cid.c_str());
        if (cat) {
          if (cat->isIncome())
            cname="<font color=green>";
          else
            cname="<font color=red>";
          cname+=QString::fromUtf8(cat->getName().c_str());
          cname+="</font>";
        }
      }
    }
  }

  tmp="<qt>";
  tmp+=pname;
  if (!cname.isEmpty()) {
    tmp+="<br>";
    tmp+=cname;
  }
  tmp+="</qt>";
  _cell[i]=new QSimpleRichText(tmp, listView()->font());
  _cell[i]->setWidth(listView()->columnWidth(i)-(2*listView()->itemMargin()));
  ht=(ht<_cell[i]->height())?_cell[i]->height():ht;
  i++;

  ht+=(2*listView()->itemMargin());
  _ht=ht;
  setHeight(ht);

  //_colour="light green";
}



// return string for sort
QString TransactionListViewItem::key(int column, bool ascending) const{
  QString result;

  result="";

  switch(column) {
  case 0: { // date
    const GWEN_TIME *ti;

    ti=_transaction.ref().getDate();
    if (!ti)
      ti=_transaction.ref().getValutaDate();
    if (ti) {
      GWEN_BUFFER *tbuf;

      tbuf=GWEN_Buffer_new(0, 32, 0, 1);
      GWEN_Time_toString(ti, "YYYYMMDD-hh:mm", tbuf);
      result=QString(GWEN_Buffer_GetStart(tbuf));
      GWEN_Buffer_free(tbuf);
    }
    else
      result=text(column);
    break;
  }

  case 5: { // value
    const AB_VALUE *v;

    v=_transaction.ref().getValue();
    if (v) {
      const char *s;
      double d;
      char numbuf[32];

      d=TRANSACTIONLIST_MAXVALUE-AB_Value_GetValue(v);
      snprintf(numbuf, sizeof(numbuf), "%012lf.2", d);
      result=QString(numbuf);
      s=AB_Value_GetCurrency(v);
      if (s) {
        result+=" ";
        result+=AB_Value_GetCurrency(v);
      }
    }
    else
      result="";
    break;
  }

  default:
    result=text(column);
    break;
  } // switch

  return result;
}



void TransactionListViewItem::setup(){
  widthChanged();
  setHeight(_ht);
}



void TransactionListViewItem::paintCell(QPainter * pnt,
                                        const QColorGroup & cg,
                                        int column,
                                        int width,
                                        int align){
  QSimpleRichText *p;
  QBrush br;

  if (column>=TRANSACTION_LISTVIEW_COLUMNS) {
    DBG_WARN(0, "WARNING: Column out of range (%d)",column);
    return;
  }
  p=_cell[column];
  if (!p) {
    DBG_DEBUG(0, "TransactionListEntry::paintCell():Invalid pointer !!");
    return;
  }
  //pnt->eraseRect(pnt->viewport());
  if (isSelected()) {
    br=QBrush(QColor("light blue"));
    //br=cg.brush(QColorGroup::Highlight);
  }
  else {
    if (!_colour.empty()) {
      br=QBrush(QColor(_colour.c_str()));
    }
    else {
      if (column & 1)
        br=QBrush(QColor("light yellow"));
        //br=cg.brush(QColorGroup::Light);
      else
        br=cg.brush(QColorGroup::Midlight);
    }
  }

  /**
  int indent=listView()->itemMargin();
  int widthPrepared=indent + p->width();
  if (width!=widthPrepared)
    p->setWidth(pnt, std::max(1, int(width - indent)));
    */

  p->draw(pnt,
          listView()->itemMargin(),
          listView()->itemMargin(),
          QRect(0, 0, width, height()),
          cg, &br);
}



int TransactionListViewItem::width(const QFontMetrics &,
                                   const QListView *lv,
                                   int column) const {
  int w;

  if (column>=TRANSACTION_LISTVIEW_COLUMNS) {
    DBG_DEBUG(0, "WARNING: Column out of range (%d)",column);
    return 0;
  }
  if (!_cell[column])
    return 0;

  w=_cell[column]->widthUsed()+lv->itemMargin()*2;
  return w;
}










TransactionListView::TransactionListView(KBanking *app,
                                         bool shortList,
                               QWidget *parent, const char *name)
:QListView(parent, name)
,_shortList(shortList)
,_app(app)
,_needUpdate(false)
,_modify(0) {
  setAllColumnsShowFocus(true);
  setShowSortIndicator(true);
  setItemMargin(2);
  addColumn(QWidget::tr("Date"),-1);
  addColumn(QWidget::tr("Institute"),-1);
  addColumn(QWidget::tr("Account"),-1);
  addColumn(QWidget::tr("Name/Purpose"),-1);
  addColumn(QWidget::tr("Type"),-1);
  addColumn(QWidget::tr("Value"),-1);
  addColumn(QWidget::tr("Payee/Category"),-1);
  setColumnAlignment(5, Qt::AlignRight);
  header()->setTracking(false);
  QObject::connect((QObject*)header(), SIGNAL(sizeChange(int, int, int)),
                   this, SLOT(slotHeaderChanged(int, int, int)));

}




TransactionListView::TransactionListView(bool shortList,
                               QWidget *parent, const char *name)
:QListView(parent, name)
,_shortList(shortList)
,_app(0)
,_needUpdate(false)
,_modify(0) {
  setAllColumnsShowFocus(true);
  setShowSortIndicator(true);
  setItemMargin(2);
  addColumn(QWidget::tr("Date"),-1);
  addColumn(QWidget::tr("Institute"),-1);
  addColumn(QWidget::tr("Account"),-1);
  addColumn(QWidget::tr("Name/Purpose"),-1);
  addColumn(QWidget::tr("Type"),-1);
  addColumn(QWidget::tr("Value"),-1);
  addColumn(QWidget::tr("Payee"),-1);
  setColumnAlignment(5, Qt::AlignRight);
  header()->setTracking(false);
  QObject::connect((QObject*)header(), SIGNAL(sizeChange(int, int, int)),
                   this, SLOT(slotHeaderChanged(int, int, int)));

}



TransactionListView::TransactionListView(QWidget *parent, const char *name)
:QListView(parent, name)
,_shortList(false)
,_app(0)
,_needUpdate(false)
,_modify(0) {
  setAllColumnsShowFocus(true);
  setShowSortIndicator(true);
  setItemMargin(2);
  addColumn(QWidget::tr("Date"),-1);
  addColumn(QWidget::tr("Institute"),-1);
  addColumn(QWidget::tr("Account"),-1);
  addColumn(QWidget::tr("Name/Purpose"),-1);
  addColumn(QWidget::tr("Type"),-1);
  addColumn(QWidget::tr("Value"),-1);
  addColumn(QWidget::tr("Payee"),-1);
  setColumnAlignment(5, Qt::AlignRight);
  header()->setTracking(false);
  QObject::connect((QObject*)header(), SIGNAL(sizeChange(int, int, int)),
                   this, SLOT(slotHeaderChanged(int, int, int)));

}



TransactionListView::~TransactionListView(){
}



bool TransactionListView::isShortList() const {
  return _shortList;
}



void TransactionListView::setShortList(bool b){
  _shortList=b;
}



void TransactionListView::addTransaction(RefPointer<Transaction> t){
  TransactionListViewItem *entry;

  entry=new TransactionListViewItem(this, t);
}



void TransactionListView::addTransactions(const std::list<RefPointer<Transaction> > &ts){
  std::list<RefPointer<Transaction> >::const_iterator it;
  int n;
  QProgressDialog *pd;
  time_t tiLast;

  beginModify();
  pd=0;
  if (ts.size()>30) {
    pd=new QProgressDialog(tr("Populating transaction list, please wait..."),
                           tr("Abort"),
                           ts.size(),
                           0, // parent
                           "ProgressDialog",
                           true);
    pd->setCaption(tr("Working..."));
    pd->setMinimumDuration(/*100*/ 0);
  }
  DBG_DEBUG(0, "Adding transactions to list view (%d)", ts.size());
  tiLast=0;
  n=0;

  for (it=ts.begin(); it!=ts.end(); it++) {
    TransactionListViewItem *entry;

    if (pd)
      pd->setProgress(n);
    entry=new TransactionListViewItem(this, *it);
    if (pd) {
      time_t ti;

      ti=time(0);
      if (!tiLast ||
          difftime(ti, tiLast)>1) {
        qApp->processEvents();
        if (pd->wasCanceled()) {
          DBG_ERROR(0, "Operation cancelled");
          break;
        }
      }
    }
    n++;
  } /* for */
  DBG_DEBUG(0, "Adding transactions to list view: done");
  if (pd) {
    pd->setProgress(n);
    delete pd;
  }
  endModify();
}



RefPointer<Transaction> TransactionListView::getCurrentTransaction() {
  TransactionListViewItem *entry;

  entry=dynamic_cast<TransactionListViewItem*>(currentItem());
  if (!entry) {
    DBG_DEBUG(0, "No item selected in list.");
    return 0;
  }
  return entry->getTransaction();
}



std::list<RefPointer<Transaction> >
TransactionListView::getSelectedTransactions(){
  std::list<RefPointer<Transaction> > ts;
  TransactionListViewItem *entry;

  // Create an iterator and give the listview as argument
  QListViewItemIterator it(this);
  // iterate through all items of the listview
  for (;it.current();++it) {
    if (it.current()->isSelected()) {
      entry=dynamic_cast<TransactionListViewItem*>(it.current());
      if (entry)
        ts.push_back(entry->getTransaction());
    }
  } // for

  return ts;
}



void TransactionListView::slotHeaderChanged(int section,
                                            int oldSize,
                                            int newSize){
  updateAll();
}



void TransactionListView::updateAll() {
  TransactionListViewItem *entry;

  if (_modify) {
    DBG_DEBUG(0, "List %p in modification progress, not updating yet",
              (void*)this);
    _needUpdate=true;
    return;
  }

  // Create an iterator and give the listview as argument
  QListViewItemIterator it(this);
  // iterate through all items of the listview
  for (;it.current();++it) {
    entry=dynamic_cast<TransactionListViewItem*>(it.current());
    if (entry) {
      entry->redrawItem((*it==currentItem()) || !_shortList);
    }
  } // for
  _needUpdate=false;
}



void TransactionListView::redrawSelected(){
  TransactionListViewItem *entry;

  // Create an iterator and give the listview as argument
  QListViewItemIterator it(this);
  // iterate through all items of the listview
  for (;it.current();++it) {
    if (it.current()->isSelected()) {
      entry=dynamic_cast<TransactionListViewItem*>(it.current());
      if (entry) {
        entry->redrawItem((*it==currentItem()) || !_shortList);
      }
    }
  } // for
}



void TransactionListView::beginModify() {
  _modify++;
  DBG_DEBUG(0, "Beginning to modify %p (%d)",
            (void*) this,
            _modify);
}



void TransactionListView::endModify() {
  _modify--;
  //if (_needUpdate)
  updateAll();
  DBG_DEBUG(0, "Modification of %p finished (%d).",
            (void*) this,
            _modify);
}



bool TransactionListView::isModifying() {
  return _modify!=0;
}

















Generated by  Doxygen 1.6.0   Back to index