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

categorylist.cpp

/***************************************************************************
 $RCSfile: categorylist.cpp,v $
                             -------------------
    cvs         : $Id: categorylist.cpp,v 1.6 2005/08/31 07:34:26 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

#define DISABLE_DEBUGLOG


#include "categorylist.h"
#include <assert.h>

#include <qstring.h>
#include <qlistview.h>

#include <qbanking/qbanking.h>

#include <gwenhywfar/debug.h>
#include <gwenhywfar/text.h>


#define CATEGORYLIST_MAXVALUE ((double)(200000000.00))


CategoryListViewItem::CategoryListViewItem(CategoryListView *parent,
                                           Category *cat)
:QListViewItem(parent)
,_category(cat){
  int i;

  assert(parent);
  assert(cat);

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

  _populate();
}



CategoryListViewItem::CategoryListViewItem(CategoryListViewItem *parent,
                                           Category *cat)
:QListViewItem(parent)
,_category(cat){
  int i;

  assert(cat);
  for (i=0; i<CATEGORY_LISTVIEW_COLUMNS; i++) {
    _cell[i]=0;
  }

  _populate();
}



CategoryListViewItem::CategoryListViewItem(const CategoryListViewItem &item)
:QListViewItem(item)
,_category(0){
  int i;

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

  if (item._category) {
    _category=item._category;
  }

}



CategoryListViewItem::CategoryListViewItem(CategoryListView *parent,
                                           QListViewItem *after,
                                           Category *cat)
:QListViewItem(parent, after)
,_category(cat){
  int i;

  assert(cat);
  for (i=0; i<CATEGORY_LISTVIEW_COLUMNS; i++) {
    _cell[i]=0;
  }

  _populate();
}



CategoryListViewItem::~CategoryListViewItem(){
}



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



void CategoryListViewItem::redrawItem() {
  CategoryListView *lv;

  lv=dynamic_cast<CategoryListView*>(listView());
  assert(lv);
  if (!(lv->isModifying())) {
    _populate();
    setup();
    repaint();
  }
}



Category *CategoryListViewItem::getCategory(){
  return _category;
}


void CategoryListViewItem::_populate() {
  QString tmp;
  QString colString;
  int i;
  int ht;
  const AB_VALUE *v;

  if (_category->isIncome())
    colString="<font color=\"dark green\">";
  else
    colString="<font color=red>";

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

  i=0;
  ht=0;

#if 0
  // category id
  tmp="<qt>";
  tmp+=colString;
  tmp+=QString::fromUtf8(_category->getId().c_str());
  tmp+="</font>";
  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++;
#endif

  // category name
  tmp="<qt>";
  tmp+=colString;
  tmp+=QString::fromUtf8(_category->getName().c_str());
  tmp+="</font>";
  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++;

  // category description
  tmp="<qt>";
  tmp+=colString;
  tmp+=QString::fromUtf8(_category->getDescription().c_str());
  tmp+="</font>";
  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++;

  // category value
  v=_category->getValue();
  tmp="<qt> <p align=right>";
  tmp+=colString;
  if (v)
    tmp+=QString::number(AB_Value_GetValue(v), 'f', 2);
  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++;

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

  //_colour="light green";
}



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



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

  if (column>=CATEGORY_LISTVIEW_COLUMNS) {
    DBG_WARN(0, "WARNING: Column out of range (%d)",column);
    return;
  }
  p=_cell[column];
  if (!p) {
    DBG_DEBUG(0, "CategoryListEntry::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 CategoryListViewItem::width(const QFontMetrics &,
                                const QListView *lv,
                                int column) const {
  int w;

  if (column>=CATEGORY_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;
}



QString CategoryListViewItem::key(int column, bool ascending) const{
  QString result;
  const AB_VALUE *v;

  result="";

  switch(column) {
  case 0: // name
    result=QString::fromUtf8(_category->getName().c_str());
    break;
  case 1: // description
    result=QString::fromUtf8(_category->getDescription().c_str());
    break;
  case 2: // amount
    v=_category->getValue();
    if (v) {
      const char *s;
      double d;
      char numbuf[32];

      d=AB_Value_GetValue(v);
      d=CATEGORYLIST_MAXVALUE-d;
      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);
  }

  return result;
}






CategoryListView::CategoryListView(QWidget *parent, const char *name)
:QListView(parent, name)
,_needUpdate(false)
,_modify(0){
  setAllColumnsShowFocus(true);
  setShowSortIndicator(true);
  addColumn(QWidget::tr("Category"),-1);
  addColumn(QWidget::tr("Description"),-1);
  addColumn(QWidget::tr("Amount"),-1);
  setColumnAlignment(2, Qt::AlignRight);
  QObject::connect((QObject*)header(), SIGNAL(sizeChange(int, int, int)),
                   this, SLOT(slotHeaderChanged(int, int, int)));
}



CategoryListView::~CategoryListView(){
}



void CategoryListView::addCategoryTo(Category *cat,
                                     CategoryListViewItem *where,
                                     const char *hiddenId){
  CategoryListViewItem *entry;
  std::list<Category*>::const_iterator it;

  beginModify();
  entry=new CategoryListViewItem(where, cat);
  for (it=cat->getChildren().begin();
       it!=cat->getChildren().end();
       it++) {
    if (!(hiddenId && *hiddenId &&
          strcasecmp((*it)->getId().c_str(), hiddenId)==0)) {
      addCategoryTo(*it, entry, hiddenId);
    }
  } // for
  endModify();
}



void CategoryListView::addCategory(Category *cat, const char *hiddenId){
  CategoryListViewItem *entry;
  std::list<Category*>::const_iterator it;

  beginModify();
  entry=new CategoryListViewItem(this, cat);
  for (it=cat->getChildren().begin();
       it!=cat->getChildren().end();
       it++) {
    if (!(hiddenId && *hiddenId &&
          strcasecmp((*it)->getId().c_str(), hiddenId)==0)) {
      addCategoryTo(*it, entry, hiddenId);
    }
  } // for
  endModify();
}



void CategoryListView::addCategories(const std::list<Category*> &cats,
                                     const char *hiddenId){
  std::list<Category*>::const_iterator it;

  beginModify();
  for (it=cats.begin(); it!=cats.end(); it++) {
    if (!(hiddenId && *hiddenId &&
          strcasecmp((*it)->getId().c_str(), hiddenId)==0)) {
      addCategory(*it, hiddenId);
    }
  } /* for */
  endModify();
}



Category *CategoryListView::getCurrentCategory() {
  CategoryListViewItem *entry;

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



std::list<Category*> CategoryListView::getSelectedCategories(){
  std::list<Category*> accs;
  CategoryListViewItem *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<CategoryListViewItem*>(it.current());
      if (entry)
        accs.push_back(entry->getCategory());
    }
  } // for

  return accs;
}



void CategoryListView::selectCategory(const char *id, bool s){
  CategoryListViewItem *entry;

  assert(id);

  DBG_DEBUG(0, "Selecting category(s): %s (%d)",
            id, s);

  beginModify();
  // 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<CategoryListViewItem*>(it.current());
    if (entry) {
      Category *cat;
      bool match=false;

      cat=entry->getCategory();
      assert(cat);
      if (-1!=GWEN_Text_ComparePattern(cat->getId().c_str(),
                                       id, 0)) {
        DBG_DEBUG(0, "Setting item \"%s\" (%s) selected (%d)",
                  cat->getId().c_str(),
                  cat->getName().c_str(),
                  s);
        setSelected(it.current(), s);
        it.current()->repaint();
        match=true;
      }
      if (!match) {
        if (it.current()->isSelected()==s) {
          DBG_DEBUG(0, "Inverting item selection to %d", !s);
          setSelected(it.current(), !s);
          it.current()->repaint();
        }
      }
    }
  } // for
  endModify();
}



void CategoryListView::selectSingleCategory(const char *id, bool s){
  CategoryListViewItem *entry;

  assert(id);

  DBG_DEBUG(0, "Selecting category: %s (%d)",
            id, s);

  beginModify();
  // 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<CategoryListViewItem*>(it.current());
    if (entry) {
      Category *cat;

      cat=entry->getCategory();
      assert(cat);
      if (strcasecmp(cat->getId().c_str(), id)==0) {
        setSelected(it.current(), s);
        it.current()->repaint();
      }
    }
  } // for
  endModify();
}



void CategoryListView::setCurrentCategory(const char *id){
  CategoryListViewItem *entry;

  assert(id);

  DBG_DEBUG(0, "Seting current category: %s", id);

  beginModify();
  // 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<CategoryListViewItem*>(it.current());
    if (entry) {
      Category *cat;

      cat=entry->getCategory();
      assert(cat);
      if (strcasecmp(cat->getId().c_str(), id)==0) {
        setCurrentItem(it.current());
        ensureItemVisible(it.current());
        break;
      }
    }
  } // for
  endModify();
}



void CategoryListView::expandAll() {
  QListViewItemIterator it(this);
  // iterate through all items of the listview
  beginModify();
  for (;it.current();++it)
    it.current()->setOpen(true);
  endModify();
}



void CategoryListView::ensureSelectionVisible(){
  // 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()) {
      ensureItemVisible(it.current());
      break;
    }
  } // for
}



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



void CategoryListView::updateAll() {
  CategoryListViewItem *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<CategoryListViewItem*>(it.current());
    if (entry) {
      entry->redrawItem();
    }
  } // for
  _needUpdate=false;
}



void CategoryListView::redrawSelected(){
  CategoryListViewItem *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<CategoryListViewItem*>(it.current());
      if (entry) {
        entry->redrawItem();
      }
    }
  } // for
}



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



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



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






Generated by  Doxygen 1.6.0   Back to index