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.
468 lines
13 KiB
468 lines
13 KiB
/***************************************************************************
|
|
transactionform.cpp
|
|
-------------------
|
|
begin : Sun May 14 2006
|
|
copyright : (C) 2006 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 <tqstring.h>
|
|
#include <tqpainter.h>
|
|
#include <tqtimer.h>
|
|
#include <tqapplication.h>
|
|
#include <tqlayout.h>
|
|
#include <tqtabbar.h>
|
|
#include <tqpalette.h>
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// KDE Includes
|
|
|
|
#include <klocale.h>
|
|
#include <kglobal.h>
|
|
#include <kdebug.h>
|
|
#include <kcombobox.h>
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Project Includes
|
|
|
|
#include <kmymoney/kmymoneydateinput.h>
|
|
#include <kmymoney/kmymoneyedit.h>
|
|
#include <kmymoney/kmymoneycategory.h>
|
|
|
|
#include "transactionform.h"
|
|
#include "../kmymoneyutils.h"
|
|
#include "../kmymoneyglobalsettings.h"
|
|
|
|
using namespace KMyMoneyTransactionForm;
|
|
|
|
TabBar::TabBar(TQWidget* parent, const char* name) :
|
|
TQTabBar(parent, name),
|
|
m_signalType(SignalNormal)
|
|
{
|
|
connect(this, TQT_SIGNAL(selected(int)), this, TQT_SLOT(slotTabSelected(int)));
|
|
}
|
|
|
|
TabBar::SignalEmissionE TabBar::setSignalEmission(TabBar::SignalEmissionE type)
|
|
{
|
|
TabBar::SignalEmissionE _type = m_signalType;
|
|
m_signalType = type;
|
|
return _type;
|
|
}
|
|
|
|
int TabBar::currentTab(void) const
|
|
{
|
|
TQMap<int, int>::const_iterator it;
|
|
it = m_idMap.find(TQTabBar::currentTab());
|
|
if(it != m_idMap.end())
|
|
return *it;
|
|
return -1;
|
|
}
|
|
|
|
void TabBar::setCurrentTab(int id)
|
|
{
|
|
if (tab(id)) // there are no tabs in an expense/income ledger
|
|
if (tab(id)->isEnabled())
|
|
setCurrentTab(tab(id));
|
|
}
|
|
|
|
TQTab* TabBar::tab(int id) const
|
|
{
|
|
/* if a TQAccel calls setCurrentTab, id will be as set by qt.
|
|
* however if we call it programmatically, id will
|
|
* be our own id. We do tell TQTab about our id but
|
|
* in qt3.3 I (woro) am not able to make sure that
|
|
* TQAccel also gets it. See registeritem.h: We defined
|
|
* new values for our own ids which should lie way
|
|
* outside of the range that qt uses
|
|
*/
|
|
TQTab *result=TQTabBar::tab(id);
|
|
TQMap<int, int>::const_iterator it;
|
|
for(it = m_idMap.begin(); it != m_idMap.end(); ++it)
|
|
if(*it == id)
|
|
result=TQTabBar::tab(it.key());
|
|
return result;
|
|
}
|
|
|
|
void TabBar::setCurrentTab(TQTab* tab)
|
|
{
|
|
if(m_signalType != SignalNormal)
|
|
blockSignals(true);
|
|
|
|
TQTabBar::setCurrentTab(tab);
|
|
|
|
if(m_signalType != SignalNormal)
|
|
blockSignals(false);
|
|
|
|
if(m_signalType == SignalAlways)
|
|
emit selected(tab->identifier());
|
|
}
|
|
|
|
void TabBar::addTab(TQTab* tab, int id)
|
|
{
|
|
TQTabBar::addTab(tab);
|
|
setIdentifier(tab, id);
|
|
}
|
|
|
|
void TabBar::setIdentifier(TQTab* tab, int newId)
|
|
{
|
|
m_idMap[tab->identifier()] = newId;
|
|
}
|
|
|
|
void TransactionForm::enableTabBar(bool b)
|
|
{
|
|
m_tabBar->setEnabled(b);
|
|
}
|
|
|
|
void TabBar::slotTabSelected(int id)
|
|
{
|
|
TQMap<int, int>::const_iterator it;
|
|
it = m_idMap.find(id);
|
|
if(it != m_idMap.end())
|
|
emit tabSelected(*it);
|
|
else
|
|
emit tabSelected(id);
|
|
}
|
|
|
|
void TabBar::show(void)
|
|
{
|
|
// make sure we don't emit a signal when simply showing the widget
|
|
if(m_signalType != SignalNormal)
|
|
blockSignals(true);
|
|
|
|
TQTabBar::show();
|
|
|
|
if(m_signalType != SignalNormal)
|
|
blockSignals(false);
|
|
}
|
|
|
|
void TabBar::copyTabs(const TabBar* otabbar)
|
|
{
|
|
// remove all existing tabs
|
|
while(count()) {
|
|
removeTab(tabAt(0));
|
|
}
|
|
// now create new ones. copy text, icon and identifier
|
|
for(int i=0; i < otabbar->count(); ++i) {
|
|
TQTab* otab = otabbar->tabAt(i);
|
|
TQTab* ntab = new TQTab(otab->text());
|
|
int nid = TQTabBar::addTab(ntab);
|
|
m_idMap[nid] = otabbar->m_idMap[otab->identifier()];
|
|
ntab->setEnabled(otab->isEnabled());
|
|
if(otab->identifier() == otabbar->currentTab())
|
|
setCurrentTab(ntab);
|
|
}
|
|
}
|
|
|
|
TransactionForm::TransactionForm(TQWidget *parent, const char *name) :
|
|
TransactionEditorContainer(parent, name),
|
|
m_transaction(0),
|
|
m_tabBar(0)
|
|
{
|
|
setBackgroundOrigin(TQTable::WindowOrigin);
|
|
setFrameShape( TQTable::NoFrame);
|
|
setShowGrid( false );
|
|
setSelectionMode( TQTable::NoSelection );
|
|
verticalHeader()->hide();
|
|
horizontalHeader()->hide();
|
|
setLeftMargin(0);
|
|
setTopMargin(0);
|
|
setReadOnly(true); // display only
|
|
|
|
// make sure, that the table is 'invisible' by setting up the right background
|
|
// keep the original color group for painting the cells though
|
|
TQPalette p = palette();
|
|
TQColorGroup cg = p.active();
|
|
m_cellColorGroup = cg;
|
|
cg.setBrush(TQColorGroup::Base, cg.brush(TQColorGroup::Background));
|
|
p.setActive(cg);
|
|
p.setInactive(cg);
|
|
p.setDisabled(cg);
|
|
setPalette(p);
|
|
|
|
// never show vertical scroll bars
|
|
setVScrollBarMode(TQScrollView::AlwaysOff);
|
|
|
|
slotSetTransaction(0);
|
|
}
|
|
|
|
void TransactionForm::drawContents( TQPainter *p, int cx, int cy, int cw, int ch )
|
|
{
|
|
// the TQTable::drawContents() method does not honor the block update flag
|
|
// so we take care of it here
|
|
if ( testWState((TQt::WidgetState)(WState_Visible|WState_BlockUpdates)) != WState_Visible )
|
|
return;
|
|
|
|
TQTable::drawContents(p, cx, cy, cw, ch);
|
|
}
|
|
|
|
bool TransactionForm::focusNextPrevChild(bool next)
|
|
{
|
|
return TQFrame::focusNextPrevChild(next);
|
|
}
|
|
|
|
void TransactionForm::clear(void)
|
|
{
|
|
slotSetTransaction(0);
|
|
}
|
|
|
|
void TransactionForm::slotSetTransaction(KMyMoneyRegister::Transaction* transaction)
|
|
{
|
|
m_transaction = transaction;
|
|
|
|
bool enabled = isUpdatesEnabled();
|
|
setUpdatesEnabled(false);
|
|
|
|
if(m_transaction) {
|
|
// the next call sets up a back pointer to the form and also sets up the col and row span
|
|
// as well as the tab of the form
|
|
m_transaction->setupForm(this);
|
|
|
|
} else {
|
|
setNumRows(5);
|
|
setNumCols(1);
|
|
}
|
|
|
|
kMyMoneyDateInput dateInput(0, "editDate");
|
|
KMyMoneyCategory category(0, "category", true);
|
|
|
|
// extract the maximal sizeHint height
|
|
int height = TQMAX(dateInput.sizeHint().height(), category.sizeHint().height());
|
|
|
|
for(int row = 0; row < numRows(); ++row) {
|
|
if(!transaction || transaction->showRowInForm(row)) {
|
|
showRow(row);
|
|
TQTable::setRowHeight(row, height);
|
|
} else
|
|
hideRow(row);
|
|
}
|
|
|
|
// adjust vertical size of form table
|
|
height *= numRows();
|
|
setMaximumHeight(height);
|
|
setMinimumHeight(height);
|
|
|
|
setUpdatesEnabled(enabled);
|
|
|
|
// force resizeing of the columns
|
|
TQTimer::singleShot(0, this, TQT_SLOT(resize()));
|
|
}
|
|
|
|
void TransactionForm::paintCell(TQPainter* painter, int row, int col, const TQRect& r, bool selected, const TQColorGroup& /* cg */)
|
|
{
|
|
if(m_transaction) {
|
|
m_transaction->paintFormCell(painter, row, col, r, selected, m_cellColorGroup);
|
|
}
|
|
}
|
|
|
|
TabBar* TransactionForm::tabBar(TQWidget* parent)
|
|
{
|
|
if(!m_tabBar && parent) {
|
|
// determine the height of the objects in the table
|
|
// create the tab bar
|
|
m_tabBar = new TabBar( parent );
|
|
m_tabBar->setSignalEmission(TabBar::SignalAlways);
|
|
m_tabBar->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)5, (TQSizePolicy::SizeType)0, 0, 0, m_tabBar->sizePolicy().hasHeightForWidth() ) );
|
|
connect(m_tabBar, TQT_SIGNAL(tabSelected(int)), this, TQT_SLOT(slotActionSelected(int)));
|
|
}
|
|
return m_tabBar;
|
|
}
|
|
|
|
void TransactionForm::slotActionSelected(int id)
|
|
{
|
|
emit newTransaction(static_cast<KMyMoneyRegister::Action>(id));
|
|
}
|
|
|
|
void TransactionForm::setupForm(const MyMoneyAccount& acc)
|
|
{
|
|
// remove all tabs from the tabbar
|
|
TQTab* tab;
|
|
for(tab = m_tabBar->tabAt(0); tab; tab = m_tabBar->tabAt(0)) {
|
|
m_tabBar->removeTab(tab);
|
|
}
|
|
|
|
m_tabBar->show();
|
|
|
|
// important: one needs to add the new tabs first and then
|
|
// change the identifier. Otherwise, addTab() will assign
|
|
// a different value
|
|
switch(acc.accountType()) {
|
|
default:
|
|
tab = new TQTab(i18n("&Deposit"));
|
|
m_tabBar->addTab(tab, KMyMoneyRegister::ActionDeposit);
|
|
tab = new TQTab(i18n("&Transfer"));
|
|
m_tabBar->addTab(tab, KMyMoneyRegister::ActionTransfer);
|
|
tab = new TQTab(i18n("&Withdrawal"));
|
|
m_tabBar->addTab(tab, KMyMoneyRegister::ActionWithdrawal);
|
|
break;
|
|
|
|
case MyMoneyAccount::CreditCard:
|
|
tab = new TQTab(i18n("&Payment"));
|
|
m_tabBar->addTab(tab, KMyMoneyRegister::ActionDeposit);
|
|
tab = new TQTab(i18n("&Transfer"));
|
|
m_tabBar->addTab(tab, KMyMoneyRegister::ActionTransfer);
|
|
tab = new TQTab(i18n("&Charge"));
|
|
m_tabBar->addTab(tab, KMyMoneyRegister::ActionWithdrawal);
|
|
break;
|
|
|
|
case MyMoneyAccount::Liability:
|
|
case MyMoneyAccount::Loan:
|
|
tab = new TQTab(i18n("&Decrease"));
|
|
m_tabBar->addTab(tab, KMyMoneyRegister::ActionDeposit);
|
|
tab = new TQTab(i18n("&Transfer"));
|
|
m_tabBar->addTab(tab, KMyMoneyRegister::ActionTransfer);
|
|
tab = new TQTab(i18n("&Increase"));
|
|
m_tabBar->addTab(tab, KMyMoneyRegister::ActionWithdrawal);
|
|
break;
|
|
|
|
case MyMoneyAccount::Asset:
|
|
case MyMoneyAccount::AssetLoan:
|
|
tab = new TQTab(i18n("&Increase"));
|
|
m_tabBar->addTab(tab, KMyMoneyRegister::ActionDeposit);
|
|
tab = new TQTab(i18n("&Transfer"));
|
|
m_tabBar->addTab(tab, KMyMoneyRegister::ActionTransfer);
|
|
tab = new TQTab(i18n("&Decrease"));
|
|
m_tabBar->addTab(tab, KMyMoneyRegister::ActionWithdrawal);
|
|
break;
|
|
|
|
case MyMoneyAccount::Income:
|
|
case MyMoneyAccount::Expense:
|
|
case MyMoneyAccount::Investment:
|
|
case MyMoneyAccount::Stock:
|
|
m_tabBar->hide();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void TransactionForm::resize(void)
|
|
{
|
|
resize(ValueColumn1);
|
|
}
|
|
|
|
void TransactionForm::resize(int col)
|
|
{
|
|
bool enabled = isUpdatesEnabled();
|
|
setUpdatesEnabled(false);
|
|
|
|
// resize the register
|
|
int w = visibleWidth();
|
|
int nc = numCols();
|
|
|
|
// check which space we need
|
|
if(nc >= LabelColumn1 && columnWidth(LabelColumn1))
|
|
adjustColumn(LabelColumn1);
|
|
if(nc >= LabelColumn2 && columnWidth(LabelColumn2))
|
|
adjustColumn(LabelColumn2);
|
|
if(nc >= ValueColumn2 && columnWidth(ValueColumn2))
|
|
adjustColumn(ValueColumn2);
|
|
|
|
for(int i = 0; i < nc; ++i) {
|
|
if(i == col)
|
|
continue;
|
|
|
|
w -= columnWidth(i);
|
|
}
|
|
if(col < nc && w >= 0)
|
|
setColumnWidth(col, w);
|
|
|
|
setUpdatesEnabled(enabled);
|
|
updateContents();
|
|
}
|
|
|
|
// needed to duplicate this here, as the TQTable::tableSize method is private :-(
|
|
TQSize TransactionForm::tableSize(void) const
|
|
{
|
|
return TQSize(columnPos(numCols()-1) + columnWidth(numCols()-1) + 10,
|
|
rowPos(numRows()-1) + rowHeight(numRows()-1) + 10);
|
|
}
|
|
|
|
TQSize TransactionForm::sizeHint(void) const
|
|
{
|
|
// I've taken this from qtable.cpp, TQTable::sizeHint()
|
|
int vmargin = TQApplication::reverseLayout() ? rightMargin() : leftMargin();
|
|
return TQSize(tableSize().width() + vmargin + 5, tableSize().height() + topMargin() + 10);
|
|
}
|
|
|
|
void TransactionForm::adjustColumn(Column col)
|
|
{
|
|
int w = 0;
|
|
|
|
// preset the width of the right value column with the width of
|
|
// the possible edit widgets so that they fit if they pop up
|
|
if(col == ValueColumn2) {
|
|
kMyMoneyDateInput dateInput;
|
|
kMyMoneyEdit valInput;
|
|
w = TQMAX(dateInput.sizeHint().width(), valInput.sizeHint().width());
|
|
}
|
|
|
|
if(m_transaction) {
|
|
TQString txt;
|
|
TQFontMetrics fontMetrics(KMyMoneyGlobalSettings::listCellFont());
|
|
|
|
// scan through the rows
|
|
for ( int i = numRows()-1; i >= 0; --i ) {
|
|
int align;
|
|
m_transaction->formCellText(txt, align, i, static_cast<int>(col), 0);
|
|
TQWidget* cw = cellWidget(i, col);
|
|
if(cw) {
|
|
w = TQMAX(w, cw->sizeHint().width()+10);
|
|
}
|
|
w = TQMAX(w, fontMetrics.width(txt)+10);
|
|
}
|
|
}
|
|
|
|
if(col < numCols())
|
|
setColumnWidth( col, w );
|
|
}
|
|
|
|
void TransactionForm::arrangeEditWidgets(TQMap<TQString, TQWidget*>& editWidgets, KMyMoneyRegister::Transaction* t)
|
|
{
|
|
t->arrangeWidgetsInForm(editWidgets);
|
|
resize(ValueColumn1);
|
|
}
|
|
|
|
void TransactionForm::tabOrder(TQWidgetList& tabOrderWidgets, KMyMoneyRegister::Transaction* t) const
|
|
{
|
|
t->tabOrderInForm(tabOrderWidgets);
|
|
}
|
|
|
|
void TransactionForm::removeEditWidgets(TQMap<TQString, TQWidget*>& editWidgets)
|
|
{
|
|
TQMap<TQString, TQWidget*>::iterator it;
|
|
for(it = editWidgets.begin(); it != editWidgets.end(); ) {
|
|
if((*it)->parentWidget() == this) {
|
|
editWidgets.remove(it);
|
|
it = editWidgets.begin();
|
|
} else
|
|
++it;
|
|
}
|
|
|
|
for(int row = 0; row < numRows(); ++row) {
|
|
for(int col = 0; col < numCols(); ++col) {
|
|
if(cellWidget(row, col))
|
|
clearCellWidget(row, col);
|
|
}
|
|
}
|
|
resize(ValueColumn1);
|
|
|
|
// delete all remaining edit widgets (e.g. tabbar)
|
|
for(it = editWidgets.begin(); it != editWidgets.end(); ) {
|
|
delete (*it); // ->deleteLater();
|
|
editWidgets.remove(it);
|
|
it = editWidgets.begin();
|
|
}
|
|
}
|
|
|
|
#include "transactionform.moc"
|