summaryrefslogtreecommitdiffstats
path: root/kmymoney2/widgets/transactionform.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmymoney2/widgets/transactionform.cpp')
-rw-r--r--kmymoney2/widgets/transactionform.cpp467
1 files changed, 467 insertions, 0 deletions
diff --git a/kmymoney2/widgets/transactionform.cpp b/kmymoney2/widgets/transactionform.cpp
new file mode 100644
index 0000000..7097b6d
--- /dev/null
+++ b/kmymoney2/widgets/transactionform.cpp
@@ -0,0 +1,467 @@
+/***************************************************************************
+ 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 <qstring.h>
+#include <qpainter.h>
+#include <qtimer.h>
+#include <qapplication.h>
+#include <qlayout.h>
+#include <qtabbar.h>
+#include <qpalette.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(QWidget* parent, const char* name) :
+ QTabBar(parent, name),
+ m_signalType(SignalNormal)
+{
+ connect(this, SIGNAL(selected(int)), this, 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
+{
+ QMap<int, int>::const_iterator it;
+ it = m_idMap.find(QTabBar::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));
+}
+
+QTab* TabBar::tab(int id) const
+{
+ /* if a QAccel calls setCurrentTab, id will be as set by qt.
+ * however if we call it programmatically, id will
+ * be our own id. We do tell QTab about our id but
+ * in qt3.3 I (woro) am not able to make sure that
+ * QAccel 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
+ */
+ QTab *result=QTabBar::tab(id);
+ QMap<int, int>::const_iterator it;
+ for(it = m_idMap.begin(); it != m_idMap.end(); ++it)
+ if(*it == id)
+ result=QTabBar::tab(it.key());
+ return result;
+}
+
+void TabBar::setCurrentTab(QTab* tab)
+{
+ if(m_signalType != SignalNormal)
+ blockSignals(true);
+
+ QTabBar::setCurrentTab(tab);
+
+ if(m_signalType != SignalNormal)
+ blockSignals(false);
+
+ if(m_signalType == SignalAlways)
+ emit selected(tab->identifier());
+}
+
+void TabBar::addTab(QTab* tab, int id)
+{
+ QTabBar::addTab(tab);
+ setIdentifier(tab, id);
+}
+
+void TabBar::setIdentifier(QTab* tab, int newId)
+{
+ m_idMap[tab->identifier()] = newId;
+}
+
+void TransactionForm::enableTabBar(bool b)
+{
+ m_tabBar->setEnabled(b);
+}
+
+void TabBar::slotTabSelected(int id)
+{
+ QMap<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);
+
+ QTabBar::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) {
+ QTab* otab = otabbar->tabAt(i);
+ QTab* ntab = new QTab(otab->text());
+ int nid = QTabBar::addTab(ntab);
+ m_idMap[nid] = otabbar->m_idMap[otab->identifier()];
+ ntab->setEnabled(otab->isEnabled());
+ if(otab->identifier() == otabbar->currentTab())
+ setCurrentTab(ntab);
+ }
+}
+
+TransactionForm::TransactionForm(QWidget *parent, const char *name) :
+ TransactionEditorContainer(parent, name),
+ m_transaction(0),
+ m_tabBar(0)
+{
+ setBackgroundOrigin(QTable::WindowOrigin);
+ setFrameShape( QTable::NoFrame);
+ setShowGrid( false );
+ setSelectionMode( QTable::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
+ QPalette p = palette();
+ QColorGroup cg = p.active();
+ m_cellColorGroup = cg;
+ cg.setBrush(QColorGroup::Base, cg.brush(QColorGroup::Background));
+ p.setActive(cg);
+ p.setInactive(cg);
+ p.setDisabled(cg);
+ setPalette(p);
+
+ // never show vertical scroll bars
+ setVScrollBarMode(QScrollView::AlwaysOff);
+
+ slotSetTransaction(0);
+}
+
+void TransactionForm::drawContents( QPainter *p, int cx, int cy, int cw, int ch )
+{
+ // the QTable::drawContents() method does not honor the block update flag
+ // so we take care of it here
+ if ( testWState(WState_Visible|WState_BlockUpdates) != WState_Visible )
+ return;
+
+ QTable::drawContents(p, cx, cy, cw, ch);
+}
+
+bool TransactionForm::focusNextPrevChild(bool next)
+{
+ return QFrame::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 = QMAX(dateInput.sizeHint().height(), category.sizeHint().height());
+
+ for(int row = 0; row < numRows(); ++row) {
+ if(!transaction || transaction->showRowInForm(row)) {
+ showRow(row);
+ QTable::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
+ QTimer::singleShot(0, this, SLOT(resize()));
+}
+
+void TransactionForm::paintCell(QPainter* painter, int row, int col, const QRect& r, bool selected, const QColorGroup& /* cg */)
+{
+ if(m_transaction) {
+ m_transaction->paintFormCell(painter, row, col, r, selected, m_cellColorGroup);
+ }
+}
+
+TabBar* TransactionForm::tabBar(QWidget* 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( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)0, 0, 0, m_tabBar->sizePolicy().hasHeightForWidth() ) );
+ connect(m_tabBar, SIGNAL(tabSelected(int)), this, 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
+ QTab* 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 QTab(i18n("&Deposit"));
+ m_tabBar->addTab(tab, KMyMoneyRegister::ActionDeposit);
+ tab = new QTab(i18n("&Transfer"));
+ m_tabBar->addTab(tab, KMyMoneyRegister::ActionTransfer);
+ tab = new QTab(i18n("&Withdrawal"));
+ m_tabBar->addTab(tab, KMyMoneyRegister::ActionWithdrawal);
+ break;
+
+ case MyMoneyAccount::CreditCard:
+ tab = new QTab(i18n("&Payment"));
+ m_tabBar->addTab(tab, KMyMoneyRegister::ActionDeposit);
+ tab = new QTab(i18n("&Transfer"));
+ m_tabBar->addTab(tab, KMyMoneyRegister::ActionTransfer);
+ tab = new QTab(i18n("&Charge"));
+ m_tabBar->addTab(tab, KMyMoneyRegister::ActionWithdrawal);
+ break;
+
+ case MyMoneyAccount::Liability:
+ case MyMoneyAccount::Loan:
+ tab = new QTab(i18n("&Decrease"));
+ m_tabBar->addTab(tab, KMyMoneyRegister::ActionDeposit);
+ tab = new QTab(i18n("&Transfer"));
+ m_tabBar->addTab(tab, KMyMoneyRegister::ActionTransfer);
+ tab = new QTab(i18n("&Increase"));
+ m_tabBar->addTab(tab, KMyMoneyRegister::ActionWithdrawal);
+ break;
+
+ case MyMoneyAccount::Asset:
+ case MyMoneyAccount::AssetLoan:
+ tab = new QTab(i18n("&Increase"));
+ m_tabBar->addTab(tab, KMyMoneyRegister::ActionDeposit);
+ tab = new QTab(i18n("&Transfer"));
+ m_tabBar->addTab(tab, KMyMoneyRegister::ActionTransfer);
+ tab = new QTab(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 QTable::tableSize method is private :-(
+QSize TransactionForm::tableSize(void) const
+{
+ return QSize(columnPos(numCols()-1) + columnWidth(numCols()-1) + 10,
+ rowPos(numRows()-1) + rowHeight(numRows()-1) + 10);
+}
+
+QSize TransactionForm::sizeHint(void) const
+{
+ // I've taken this from qtable.cpp, QTable::sizeHint()
+ int vmargin = QApplication::reverseLayout() ? rightMargin() : leftMargin();
+ return QSize(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 = QMAX(dateInput.sizeHint().width(), valInput.sizeHint().width());
+ }
+
+ if(m_transaction) {
+ QString txt;
+ QFontMetrics 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);
+ QWidget* cw = cellWidget(i, col);
+ if(cw) {
+ w = QMAX(w, cw->sizeHint().width()+10);
+ }
+ w = QMAX(w, fontMetrics.width(txt)+10);
+ }
+ }
+
+ if(col < numCols())
+ setColumnWidth( col, w );
+}
+
+void TransactionForm::arrangeEditWidgets(QMap<QString, QWidget*>& editWidgets, KMyMoneyRegister::Transaction* t)
+{
+ t->arrangeWidgetsInForm(editWidgets);
+ resize(ValueColumn1);
+}
+
+void TransactionForm::tabOrder(QWidgetList& tabOrderWidgets, KMyMoneyRegister::Transaction* t) const
+{
+ t->tabOrderInForm(tabOrderWidgets);
+}
+
+void TransactionForm::removeEditWidgets(QMap<QString, QWidget*>& editWidgets)
+{
+ QMap<QString, QWidget*>::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"