/*************************************************************************** transactionform.cpp ------------------- begin : Sun May 14 2006 copyright : (C) 2006 by Thomas Baumgart email : Thomas Baumgart ***************************************************************************/ /*************************************************************************** * * * 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 #endif // ---------------------------------------------------------------------------- // TQt Includes #include #include #include #include #include #include #include // ---------------------------------------------------------------------------- // TDE Includes #include #include #include #include // ---------------------------------------------------------------------------- // Project Includes #include #include #include #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, TQ_SIGNAL(selected(int)), this, TQ_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::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 tqt. * 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 tqt uses */ TQTab *result=TQTabBar::tab(id); TQMap::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::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, TQ_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, TQ_SIGNAL(tabSelected(int)), this, TQ_SLOT(slotActionSelected(int))); } return m_tabBar; } void TransactionForm::slotActionSelected(int id) { emit newTransaction(static_cast(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(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& 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& editWidgets) { TQMap::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"