/***************************************************************************
                          kfindtransactiondlg.cpp
                             -------------------
    copyright            : (C) 2003, 2007 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.                                   *
 *                                                                         *
 ***************************************************************************/

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

// ----------------------------------------------------------------------------
// TQt Includes

#include <tqlabel.h>
#include <tqradiobutton.h>
#include <tqcheckbox.h>
#include <tqtimer.h>
#include <tqtabwidget.h>
#include <tqlayout.h>

// ----------------------------------------------------------------------------
// TDE Includes

#include <tdeapplication.h>
#include <tdeglobal.h>
#include <tdelocale.h>
#include <tdestandarddirs.h>
#include <kpushbutton.h>
#include <klineedit.h>
#include <tdelistview.h>
#include <kcombobox.h>
#include <kstdguiitem.h>
#include <kiconloader.h>

// ----------------------------------------------------------------------------
// Project Includes

#include "kfindtransactiondlg.h"

#include <kmymoney/kmymoneydateinput.h>
#include <kmymoney/kmymoneyedit.h>
#include <kmymoney/kmymoneylineedit.h>
#include <kmymoney/kmymoneyaccountselector.h>
#include <kmymoney/mymoneyfile.h>
#include <kmymoney/kmymoneychecklistitem.h>
#include <kmymoney/kmymoneyglobalsettings.h>
#include <kmymoney/register.h>
#include <kmymoney/transaction.h>
#include <kmymoney/kmymoneycombo.h>

#include "ksortoptiondlg.h"

KFindTransactionDlg::KFindTransactionDlg(TQWidget *parent, const char *name) :
  KFindTransactionDlgDecl(parent, name, false),
  m_needReload(false)
{
  m_register->installEventFilter(this);
  m_tabWidget->setTabEnabled(m_resultPage, false);

  // 'cause we don't have a separate setupTextPage
  connect(m_textEdit, TQ_SIGNAL(textChanged(const TQString&)), this, TQ_SLOT(slotUpdateSelections()));

  setupAccountsPage();
  setupCategoriesPage();
  setupDatePage();
  setupAmountPage();
  setupPayeesPage();
  setupDetailsPage();

  // We don't need to add the default into the list (see ::slotShowHelp() why)
  // m_helpAnchor[m_textTab] = TQString("details.search");
  m_helpAnchor[m_accountTab] = TQString("details.search.account");
  m_helpAnchor[m_dateTab] = TQString("details.search.date");
  m_helpAnchor[m_amountTab] = TQString("details.search.amount");
  m_helpAnchor[m_categoryTab] = TQString("details.search.category");
  m_helpAnchor[m_payeeTab] = TQString("details.search.payee");
  m_helpAnchor[m_detailsTab] = TQString("details.search.details");

  // setup the register
  TQValueList<KMyMoneyRegister::Column> cols;
  cols << KMyMoneyRegister::DateColumn;
  cols << KMyMoneyRegister::AccountColumn;
  cols << KMyMoneyRegister::DetailColumn;
  cols << KMyMoneyRegister::ReconcileFlagColumn;
  cols << KMyMoneyRegister::PaymentColumn;
  cols << KMyMoneyRegister::DepositColumn;
  m_register->setupRegister(MyMoneyAccount(), cols);
  m_register->setSelectionMode(TQTable::Single);

  connect(m_register, TQ_SIGNAL(editTransaction()), this, TQ_SLOT(slotSelectTransaction()));
  connect(m_register, TQ_SIGNAL(headerClicked()), this, TQ_SLOT(slotSortOptions()));

  slotUpdateSelections();

  // setup the connections
  connect(m_searchButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotSearch()));
  connect(m_resetButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotReset()));
  connect(m_resetButton, TQ_SIGNAL(clicked()), m_accountsView, TQ_SLOT(slotSelectAllAccounts()));
  connect(m_resetButton, TQ_SIGNAL(clicked()), m_categoriesView, TQ_SLOT(slotSelectAllAccounts()));
  connect(m_closeButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(deleteLater()));
  connect(m_helpButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotShowHelp()));

  // only allow searches when a selection has been made
  connect(this, TQ_SIGNAL(selectionEmpty(bool)), m_searchButton, TQ_SLOT(setDisabled(bool)));

  // get signal about engine changes
  connect(MyMoneyFile::instance(), TQ_SIGNAL(dataChanged()), this, TQ_SLOT(slotRefreshView()));

  slotUpdateSelections();

  m_textEdit->setFocus();
}

void KFindTransactionDlg::slotReset(void)
{
  m_textEdit->setText(TQString());
  m_regExp->setChecked(false);
  m_caseSensitive->setChecked(false);
  m_textNegate->setCurrentItem(0);

  m_amountEdit->setEnabled(true);
  m_amountFromEdit->setEnabled(false);
  m_amountToEdit->setEnabled(false);
  m_amountEdit->loadText(TQString());
  m_amountFromEdit->loadText(TQString());
  m_amountToEdit->loadText(TQString());
  m_amountButton->setChecked(true);
  m_amountRangeButton->setChecked(false);

  m_emptyPayeesButton->setChecked(false);
  selectAllItems(m_payeesView, true);

  m_typeBox->setCurrentItem(MyMoneyTransactionFilter::allTypes);
  m_stateBox->setCurrentItem(MyMoneyTransactionFilter::allStates);
  m_validityBox->setCurrentItem(MyMoneyTransactionFilter::anyValidity);

  m_nrEdit->setEnabled(true);
  m_nrFromEdit->setEnabled(false);
  m_nrToEdit->setEnabled(false);
  m_nrEdit->setText(TQString());
  m_nrFromEdit->setText(TQString());
  m_nrToEdit->setText(TQString());
  m_nrButton->setChecked(true);
  m_nrRangeButton->setChecked(false);

  m_tabWidget->setTabEnabled(m_resultPage, false);
  m_tabWidget->setCurrentPage(m_tabWidget->indexOf(m_criteriaTab));

  // the following call implies a call to slotUpdateSelections,
  // that's why we call it last
  m_dateRange->setCurrentItem(MyMoneyTransactionFilter::allDates);
  slotDateRangeChanged(MyMoneyTransactionFilter::allDates);
}

void KFindTransactionDlg::slotUpdateSelections(void)
{
  TQString txt;

  // Text tab
  if(!m_textEdit->text().isEmpty()) {
    if(!txt.isEmpty())
      txt += ", ";
    txt += i18n("Text");
    m_regExp->setEnabled(TQRegExp(m_textEdit->text()).isValid());
  } else
    m_regExp->setEnabled(false);

  m_caseSensitive->setEnabled(!m_textEdit->text().isEmpty());
  m_textNegate->setEnabled(!m_textEdit->text().isEmpty());

  // Account tab
  if(!m_accountsView->allItemsSelected()) {
    if(!txt.isEmpty())
      txt += ", ";
    txt += i18n("Account");
  }

  // Date tab
  if(m_dateRange->currentItem() != 0) {
    if(!txt.isEmpty())
      txt += ", ";
    txt += i18n("Date");
  }

  // Amount tab
  if((m_amountButton->isChecked() && m_amountEdit->isValid())
  || (m_amountRangeButton->isChecked()
      && (m_amountFromEdit->isValid() || m_amountToEdit->isValid()))) {
    if(!txt.isEmpty())
      txt += ", ";
    txt += i18n("Amount");
  }

  // Categories tab
  if(!m_categoriesView->allItemsSelected()) {
    if(!txt.isEmpty())
      txt += ", ";
    txt += i18n("Category");
  }

  // Payees tab
  if(!allItemsSelected(m_payeesView)
  || m_emptyPayeesButton->isChecked()) {
    if(!txt.isEmpty())
      txt += ", ";
    txt += i18n("Payees");
  }
  m_payeesView->setEnabled(!m_emptyPayeesButton->isChecked());

  // Details tab
  if(m_typeBox->currentItem() != 0
  || m_stateBox->currentItem() != 0
  || m_validityBox->currentItem() != 0
  || (m_nrButton->isChecked() && m_nrEdit->text().length() != 0)
  || (m_nrRangeButton->isChecked()
     && (m_nrFromEdit->text().length() != 0 || m_nrToEdit->text().length() != 0))) {
    if(!txt.isEmpty())
      txt += ", ";
    txt += i18n("Details");
  }

  //Show a warning about transfers if Categories are filtered - bug #1523508
  if(!m_categoriesView->allItemsSelected()) {
    m_transferWarning->setText( i18n("Warning: Filtering by Category will exclude all transfers from the results.") );
  } else {
    m_transferWarning->setText("");
  }

  // disable the search button if no selection is made
  emit selectionEmpty(txt.isEmpty());

  if(txt.isEmpty()) {
    txt = i18n("(None)");
  }
  m_selectedCriteria->setText(i18n("Current selections: ") + txt);
}

bool KFindTransactionDlg::allItemsSelected(const TQListViewItem *item) const
{
  TQListViewItem* it_v;

  for(it_v = item->firstChild(); it_v != 0; it_v = it_v->nextSibling()) {
    if(it_v->rtti() == 1) {
      TQCheckListItem* it_c = static_cast<TQCheckListItem*>(it_v);
      if(!(it_c->isOn() && allItemsSelected(it_v)))
        return false;
    }
  }
  return true;
}

bool KFindTransactionDlg::allItemsSelected(const TQListView* view) const
{
  TQListViewItem* it_v;

  for(it_v = view->firstChild(); it_v != 0; it_v = it_v->nextSibling()) {
    if(it_v->rtti() == 1) {
      TQCheckListItem* it_c = static_cast<TQCheckListItem*>(it_v);
      if(it_c->type() == TQCheckListItem::CheckBox) {
        if(!(it_c->isOn() && allItemsSelected(it_v)))
          return false;
      } else {
        if(!allItemsSelected(it_v))
          return false;
      }
    }
  }
  return true;
}

void KFindTransactionDlg::setupAccountsPage(void)
{
  m_accountsView->setSelectionMode(TQListView::Multi);
  AccountSet accountSet;
  accountSet.addAccountGroup(MyMoneyAccount::Asset);
  accountSet.addAccountGroup(MyMoneyAccount::Liability);
  //set the accountset to show closed account if the settings say so
  accountSet.setHideClosedAccounts(KMyMoneyGlobalSettings::hideClosedAccounts());
  accountSet.load(m_accountsView);
  connect(m_accountsView, TQ_SIGNAL(stateChanged()), this, TQ_SLOT(slotUpdateSelections()));
}

void KFindTransactionDlg::selectAllItems(TQListView* view, const bool state)
{
  TQListViewItem* it_v;

  for(it_v = view->firstChild(); it_v != 0; it_v = it_v->nextSibling()) {
    TQCheckListItem* it_c = static_cast<TQCheckListItem*>(it_v);
    if(it_c->type() == TQCheckListItem::CheckBox) {
      it_c->setOn(state);
    }
    selectAllSubItems(it_v, state);
  }

  slotUpdateSelections();
}

void KFindTransactionDlg::selectItems(TQListView* view, const TQStringList& list, const bool state)
{
  TQListViewItem* it_v;

  for(it_v = view->firstChild(); it_v != 0; it_v = it_v->nextSibling()) {
    KMyMoneyCheckListItem* it_c = static_cast<KMyMoneyCheckListItem*>(it_v);
    if(it_c->type() == TQCheckListItem::CheckBox && list.contains(it_c->id())) {
      it_c->setOn(state);
    }
    selectSubItems(it_v, list, state);
  }

  slotUpdateSelections();
}

void KFindTransactionDlg::setupCategoriesPage(void)
{
  m_categoriesView->setSelectionMode(TQListView::Multi);
  AccountSet categorySet;
  categorySet.addAccountGroup(MyMoneyAccount::Income);
  categorySet.addAccountGroup(MyMoneyAccount::Expense);
  categorySet.load(m_categoriesView);
  connect(m_categoriesView, TQ_SIGNAL(stateChanged()), this, TQ_SLOT(slotUpdateSelections()));
}

void KFindTransactionDlg::selectAllSubItems(TQListViewItem* item, const bool state)
{
  TQListViewItem* it_v;

  for(it_v = item->firstChild(); it_v != 0; it_v = it_v->nextSibling()) {
    static_cast<TQCheckListItem*>(it_v)->setOn(state);
    selectAllSubItems(it_v, state);
  }
}

void KFindTransactionDlg::selectSubItems(TQListViewItem* item, const TQStringList& list, const bool state)
{
  TQListViewItem* it_v;

  for(it_v = item->firstChild(); it_v != 0; it_v = it_v->nextSibling()) {
    KMyMoneyCheckListItem* it_c = static_cast<KMyMoneyCheckListItem*>(it_v);
    if(list.contains(it_c->id()))
      it_c->setOn(state);
    selectSubItems(it_v, list, state);
  }
}

void KFindTransactionDlg::setupDatePage(void)
{
  int i;
  for(i = MyMoneyTransactionFilter::allDates; i < MyMoneyTransactionFilter::dateOptionCount; ++i) {
    MyMoneyTransactionFilter::translateDateRange(static_cast<MyMoneyTransactionFilter::dateOptionE>(i), m_startDates[i], m_endDates[i]);
  }

  connect(m_dateRange, TQ_SIGNAL(itemSelected(int)), this, TQ_SLOT(slotDateRangeChanged(int)));
  connect(m_fromDate, TQ_SIGNAL(dateChanged(const TQDate&)), this, TQ_SLOT(slotDateChanged()));
  connect(m_toDate, TQ_SIGNAL(dateChanged(const TQDate&)), this, TQ_SLOT(slotDateChanged()));

  slotDateRangeChanged(MyMoneyTransactionFilter::allDates);
}

void KFindTransactionDlg::slotDateRangeChanged(int idx)
{
  switch(idx) {
    case MyMoneyTransactionFilter::allDates:
    case MyMoneyTransactionFilter::userDefined:
      m_fromDate->loadDate(TQDate());
      m_toDate->loadDate(TQDate());
      break;
    default:
      m_fromDate->loadDate(m_startDates[idx]);
      m_toDate->loadDate(m_endDates[idx]);
      break;
  }
  slotUpdateSelections();
}

void KFindTransactionDlg::slotDateChanged(void)
{
  int idx;
  for(idx = MyMoneyTransactionFilter::asOfToday; idx < MyMoneyTransactionFilter::dateOptionCount; ++idx) {
    if(m_fromDate->date() == m_startDates[idx]
    && m_toDate->date() == m_endDates[idx]) {
      break;
    }
  }
  //if no filter matched, set to user defined
  if(idx == MyMoneyTransactionFilter::dateOptionCount)
    idx = MyMoneyTransactionFilter::userDefined;

  m_dateRange->blockSignals(true);
  m_dateRange->setCurrentItem(static_cast<MyMoneyTransactionFilter::dateOptionE>(idx));
  m_dateRange->blockSignals(false);
  slotUpdateSelections();
}

void KFindTransactionDlg::setupAmountPage(void)
{
  connect(m_amountButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotAmountSelected()));
  connect(m_amountRangeButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotAmountRangeSelected()));

  connect(m_amountEdit, TQ_SIGNAL(textChanged(const TQString&)), this, TQ_SLOT(slotUpdateSelections()));
  connect(m_amountFromEdit, TQ_SIGNAL(textChanged(const TQString&)), this, TQ_SLOT(slotUpdateSelections()));
  connect(m_amountToEdit, TQ_SIGNAL(textChanged(const TQString&)), this, TQ_SLOT(slotUpdateSelections()));

  m_amountButton->setChecked(true);
  slotAmountSelected();
}

void KFindTransactionDlg::slotAmountSelected(void)
{
  m_amountEdit->setEnabled(true);
  m_amountFromEdit->setEnabled(false);
  m_amountToEdit->setEnabled(false);
  slotUpdateSelections();
}

void KFindTransactionDlg::slotAmountRangeSelected(void)
{
  m_amountEdit->setEnabled(false);
  m_amountFromEdit->setEnabled(true);
  m_amountToEdit->setEnabled(true);
  slotUpdateSelections();
}

void KFindTransactionDlg::setupPayeesPage(void)
{
  m_payeesView->setSelectionMode(TQListView::Single);
  m_payeesView->header()->hide();

  loadPayees();
  m_emptyPayeesButton->setChecked(false);

  connect(m_allPayeesButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotSelectAllPayees()));
  connect(m_clearPayeesButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotDeselectAllPayees()));
  connect(m_emptyPayeesButton, TQ_SIGNAL(stateChanged(int)), this, TQ_SLOT(slotUpdateSelections()));
}

void KFindTransactionDlg::loadPayees(void)
{
  MyMoneyFile* file = MyMoneyFile::instance();
  TQValueList<MyMoneyPayee> list;
  TQValueList<MyMoneyPayee>::Iterator it_l;

  list = file->payeeList();
  // load view
  for(it_l = list.begin(); it_l != list.end(); ++it_l) {
    KMyMoneyCheckListItem* item = new KMyMoneyCheckListItem(m_payeesView, (*it_l).name(), TQString(), (*it_l).id());
    connect(item, TQ_SIGNAL(stateChanged(bool)), this, TQ_SLOT(slotUpdateSelections()));
    item->setOn(true);
  }
}
void KFindTransactionDlg::slotSelectAllPayees(void)
{
  selectAllItems(m_payeesView, true);
}

void KFindTransactionDlg::slotDeselectAllPayees(void)
{
  selectAllItems(m_payeesView, false);
}

void KFindTransactionDlg::setupDetailsPage(void)
{
  connect(m_typeBox, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotUpdateSelections()));
  connect(m_stateBox, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotUpdateSelections()));
  connect(m_validityBox, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotUpdateSelections()));

  connect(m_nrButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotNrSelected()));
  connect(m_nrRangeButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotNrRangeSelected()));
  connect(m_nrEdit, TQ_SIGNAL(textChanged(const TQString&)), this, TQ_SLOT(slotUpdateSelections()));
  connect(m_nrFromEdit, TQ_SIGNAL(textChanged(const TQString&)), this, TQ_SLOT(slotUpdateSelections()));
  connect(m_nrToEdit, TQ_SIGNAL(textChanged(const TQString&)), this, TQ_SLOT(slotUpdateSelections()));

  m_nrButton->setChecked(true);
  slotNrSelected();
}

void KFindTransactionDlg::slotNrSelected(void)
{
  m_nrEdit->setEnabled(true);
  m_nrFromEdit->setEnabled(false);
  m_nrToEdit->setEnabled(false);
  slotUpdateSelections();
}

void KFindTransactionDlg::slotNrRangeSelected(void)
{
  m_nrEdit->setEnabled(false);
  m_nrFromEdit->setEnabled(true);
  m_nrToEdit->setEnabled(true);
  slotUpdateSelections();
}

void KFindTransactionDlg::addItemToFilter(const opTypeE op, const TQString& id)
{
  switch(op) {
    case addAccountToFilter:
      m_filter.addAccount(id);
      break;
    case addCategoryToFilter:
      m_filter.addCategory(id);
      break;
    case addPayeeToFilter:
      m_filter.addPayee(id);
      break;
  }
}

void KFindTransactionDlg::scanCheckListItems(const TQListViewItem* item, const opTypeE op)
{
  TQListViewItem* it_v;

  for(it_v = item->firstChild(); it_v != 0; it_v = it_v->nextSibling()) {
    if(it_v->rtti() == 1) {
      KMyMoneyCheckListItem* it_c = static_cast<KMyMoneyCheckListItem*>(it_v);
      if(it_c->type() == TQCheckListItem::CheckBox) {
        if(it_c->isOn())
          addItemToFilter(op, (*it_c).id());
      }
      scanCheckListItems(it_v, op);
    }
  }
}

void KFindTransactionDlg::scanCheckListItems(const TQListView* view, const opTypeE op)
{
  TQListViewItem* it_v;

  for(it_v = view->firstChild(); it_v != 0; it_v = it_v->nextSibling()) {
    if(it_v->rtti() == 1) {
      KMyMoneyCheckListItem* it_c = static_cast<KMyMoneyCheckListItem*>(it_v);
      if(it_c->type() == TQCheckListItem::CheckBox) {
        if(it_c->isOn())
          addItemToFilter(op, (*it_c).id());
      }
      scanCheckListItems(it_v, op);
    }
  }
}

void KFindTransactionDlg::setupFilter(void)
{
  m_filter.clear();

  // Text tab
  if(!m_textEdit->text().isEmpty()) {
    TQRegExp exp(m_textEdit->text(), m_caseSensitive->isChecked(), !m_regExp->isChecked());
    m_filter.setTextFilter(exp, m_textNegate->currentItem() != 0);
  }

  // Account tab
  if(!m_accountsView->allItemsSelected()) {
    // retrieve a list of selected accounts
    TQStringList list;
    m_accountsView->selectedItems(list);

    // if we're not in expert mode, we need to make sure
    // that all stock accounts for the selected investment
    // account are also selected
    if(!KMyMoneyGlobalSettings::expertMode()) {
      TQStringList missing;
      TQStringList::const_iterator it_a, it_b;
      for(it_a = list.begin(); it_a != list.end(); ++it_a) {
        MyMoneyAccount acc = MyMoneyFile::instance()->account(*it_a);
        if(acc.accountType() == MyMoneyAccount::Investment) {
          for(it_b = acc.accountList().begin(); it_b != acc.accountList().end(); ++it_b) {
            if(!list.contains(*it_b)) {
              missing.append(*it_b);
            }
          }
        }
      }
      list += missing;
    }

    m_filter.addAccount(list);
  }

  // Date tab
  if(m_dateRange->currentItem() != 0) {
    m_filter.setDateFilter(m_fromDate->date(), m_toDate->date());
  }

  // Amount tab
  if((m_amountButton->isChecked() && m_amountEdit->isValid())) {
    m_filter.setAmountFilter(m_amountEdit->value(), m_amountEdit->value());

  } else if((m_amountRangeButton->isChecked()
      && (m_amountFromEdit->isValid() || m_amountToEdit->isValid()))) {

    MyMoneyMoney from(MyMoneyMoney::minValue), to(MyMoneyMoney::maxValue);
    if(m_amountFromEdit->isValid())
      from = m_amountFromEdit->value();
    if(m_amountToEdit->isValid())
      to = m_amountToEdit->value();

    m_filter.setAmountFilter(from, to);
  }

  // Categories tab
  if(!m_categoriesView->allItemsSelected()) {
    m_filter.addCategory(m_categoriesView->selectedItems());
  }

  // Payees tab
  if(m_emptyPayeesButton->isChecked()) {
    m_filter.addPayee(TQString());

  } else if(!allItemsSelected(m_payeesView)) {
    scanCheckListItems(m_payeesView, addPayeeToFilter);
  }

  // Details tab
  if(m_typeBox->currentItem() != 0)
    m_filter.addType(m_typeBox->currentItem());

  if(m_stateBox->currentItem() != 0)
    m_filter.addState(m_stateBox->currentItem());

  if(m_validityBox->currentItem() != 0)
    m_filter.addValidity(m_validityBox->currentItem());

  if(m_nrButton->isChecked() && !m_nrEdit->text().isEmpty())
    m_filter.setNumberFilter(m_nrEdit->text(), m_nrEdit->text());

  if(m_nrRangeButton->isChecked()
     && (!m_nrFromEdit->text().isEmpty() || !m_nrToEdit->text().isEmpty())) {
    m_filter.setNumberFilter(m_nrFromEdit->text(), m_nrToEdit->text());
  }
}

void KFindTransactionDlg::slotSearch(void)
{
  // setup the filter from the dialog widgets
  setupFilter();

  // filter is setup, now fill the register
  slotRefreshView();

  m_register->setFocus();
}

void KFindTransactionDlg::slotRefreshView(void)
{
  m_needReload = true;
  if(isVisible()) {
    loadView();
    m_needReload = false;
  }
}

void KFindTransactionDlg::show(void)
{
  if(m_needReload) {
    loadView();
    m_needReload = false;
  }
  KFindTransactionDlgDecl::show();
}

void KFindTransactionDlg::loadView(void)
{
  // setup sort order
  m_register->setSortOrder(KMyMoneyGlobalSettings::sortSearchView());

  // clear out old data
  m_register->clear();

  // retrieve the list from the engine
  MyMoneyFile::instance()->transactionList(m_transactionList, m_filter);

    // create the elements for the register
  TQValueList<TQPair<MyMoneyTransaction, MyMoneySplit> >::const_iterator it;
  TQMap<TQString, int>uniqueMap;
  MyMoneyMoney deposit, payment;

  int splitCount = 0;
  for(it = m_transactionList.begin(); it != m_transactionList.end(); ++it) {
    const MyMoneySplit& split = (*it).second;
    MyMoneyAccount acc = MyMoneyFile::instance()->account(split.accountId());
    ++splitCount;
    uniqueMap[(*it).first.id()]++;

    KMyMoneyRegister::Register::transactionFactory(m_register, (*it).first, (*it).second, uniqueMap[(*it).first.id()]);
    { // debug stuff
      if(split.shares().isNegative()) {
        payment += split.shares().abs();
      } else {
        deposit += split.shares().abs();
      }
    }
  }

    // add the group markers
  m_register->addGroupMarkers();

    // sort the transactions according to the sort setting
  m_register->sortItems();

    // remove trailing and adjacent markers
  m_register->removeUnwantedGroupMarkers();

  // turn on the ledger lens for the register
  m_register->setLedgerLensForced();

  m_register->updateRegister(true);

  m_register->setFocusToTop();
  m_register->selectItem(m_register->focusItem());

#if KMM_DEBUG
  m_foundText->setText(i18n("Found %1 matching transactions (D %2 / P %3 = %4)")
                      .arg(splitCount).arg(deposit.formatMoney("", 2)).arg(payment.formatMoney("", 2)).arg((deposit-payment).formatMoney("", 2)));
#else
  m_foundText->setText(i18n("Found %1 matching transactions") .arg(splitCount));
#endif

  m_tabWidget->setTabEnabled(m_resultPage, true);
  m_tabWidget->setCurrentPage(m_tabWidget->indexOf(m_resultPage));

  TQTimer::singleShot(10, this, TQ_SLOT(slotRightSize()));
}

void KFindTransactionDlg::slotRightSize(void)
{
  m_register->updateContents();
}

void KFindTransactionDlg::resizeEvent(TQResizeEvent* ev)
{
  // Columns
  // 1 = Date
  // 2 = Account
  // 4 = Detail
  // 5 = C
  // 6 = Payment
  // 7 = Deposit

  // don't forget the resizer
  KFindTransactionDlgDecl::resizeEvent(ev);

  if(!m_register->isVisible())
    return;

  // resize the register
  int w = m_register->visibleWidth();

  int m_debitWidth = 80;
  int m_creditWidth = 80;

  m_register->adjustColumn(1);
  m_register->adjustColumn(2);
  m_register->adjustColumn(5);

  m_register->setColumnWidth(6, m_debitWidth);
  m_register->setColumnWidth(7, m_creditWidth);

  for(int i = 0; i < m_register->numCols(); ++i) {
    switch(i) {
      case 4:     // skip the one, we want to set
        break;
      default:
        w -= m_register->columnWidth(i);
        break;
    }
  }

  m_register->setColumnWidth(4, w);
}


void KFindTransactionDlg::slotSelectTransaction(void)
{
  TQValueList<KMyMoneyRegister::RegisterItem*> list = m_register->selectedItems();
  if(!list.isEmpty()) {
    KMyMoneyRegister::Transaction* t = dynamic_cast<KMyMoneyRegister::Transaction*>(list[0]);
    if(t) {
      emit transactionSelected(t->split().accountId(), t->transaction().id());
      hide();
    }
  }
}

bool KFindTransactionDlg::eventFilter(TQObject* o, TQEvent* e)
{
  bool rc = false;

  if(o->isWidgetType()) {
    if(e->type() == TQEvent::KeyPress) {
      const TQWidget* w = dynamic_cast<const TQWidget*>(o);
      TQKeyEvent *k = static_cast<TQKeyEvent*> (e);
      if(w == m_register) {
        switch(k->key()) {
          default:
            break;

          case TQt::Key_Return:
          case TQt::Key_Enter:
            rc = true;
            slotSelectTransaction();
            break;
        }
      }
    }
  }
  return rc;
}

void KFindTransactionDlg::slotShowHelp(void)
{
  TQString anchor = m_helpAnchor[m_criteriaTab->currentPage()];
  if(anchor.isEmpty())
    anchor = TQString("details.search");

  tdeApp->invokeHelp(anchor);
}

void KFindTransactionDlg::slotSortOptions(void)
{
  KSortOptionDlg* dlg = new KSortOptionDlg(this);

  dlg->setSortOption(KMyMoneyGlobalSettings::sortSearchView(), TQString());
  dlg->hideDefaultButton();

  if(dlg->exec() == TQDialog::Accepted) {
    TQString sortOrder = dlg->sortOption();
    if(sortOrder != KMyMoneyGlobalSettings::sortSearchView()) {
      KMyMoneyGlobalSettings::setSortSearchView(sortOrder);
      slotRefreshView();
    }
  }
  delete dlg;
}
#include "kfindtransactiondlg.moc"
