Warning, file /office/kmymoney/kmymoney/widgets/transactionform.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2006-2018 Thomas Baumgart <tbaumgart@kde.org>
0003     SPDX-FileCopyrightText: 2017-2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "transactionform.h"
0008 
0009 // ----------------------------------------------------------------------------
0010 // QT Includes
0011 
0012 #include <QString>
0013 #include <QPalette>
0014 #include <QFrame>
0015 #include <QHeaderView>
0016 #include <QPushButton>
0017 #include <QMouseEvent>
0018 #include <QKeyEvent>
0019 
0020 // ----------------------------------------------------------------------------
0021 // KDE Includes
0022 
0023 #include <KLocalizedString>
0024 
0025 // ----------------------------------------------------------------------------
0026 // Project Includes
0027 
0028 #include "transactionformitemdelegate.h"
0029 #include "tabbar.h"
0030 #include "amountedit.h"
0031 #include "mymoneyaccount.h"
0032 #include "kmymoneydateinput.h"
0033 #include "kmymoneycategory.h"
0034 #include "transaction.h"
0035 
0036 #include "kmymoneysettings.h"
0037 
0038 #include "widgetenums.h"
0039 #include "mymoneyenums.h"
0040 
0041 using namespace eWidgets;
0042 using namespace KMyMoneyTransactionForm;
0043 
0044 namespace KMyMoneyTransactionForm
0045 {
0046 class TransactionFormPrivate
0047 {
0048     Q_DISABLE_COPY(TransactionFormPrivate)
0049 
0050 public:
0051     TransactionFormPrivate() :
0052         m_transaction(nullptr),
0053         m_tabBar(nullptr),
0054         m_itemDelegate(nullptr)
0055     {
0056     }
0057 
0058     KMyMoneyRegister::Transaction   *m_transaction;
0059     KMyMoneyTransactionForm::TabBar *m_tabBar;
0060     TransactionFormItemDelegate     *m_itemDelegate;
0061 };
0062 }
0063 
0064 TransactionForm::TransactionForm(QWidget *parent) :
0065     TransactionEditorContainer(parent),
0066     d_ptr(new TransactionFormPrivate)
0067 {
0068     Q_D(TransactionForm);
0069     d->m_itemDelegate = new TransactionFormItemDelegate(this);
0070     setFrameShape(QTableWidget::NoFrame);
0071     setShowGrid(false);
0072     setSelectionMode(QTableWidget::NoSelection);
0073     verticalHeader()->hide();
0074     horizontalHeader()->hide();
0075 
0076     setEditTriggers(QAbstractItemView::NoEditTriggers);
0077 
0078     // make sure, that the table is 'invisible' by setting up the right background
0079     // keep the original color group for painting the cells though
0080     QPalette p = palette();
0081     QBrush brush = p.brush(QPalette::Background);
0082     QColor color = brush.color();
0083     color.setAlpha(0);
0084     brush.setColor(color);
0085     p.setBrush(QPalette::Active, QPalette::Base, brush);
0086     p.setBrush(QPalette::Inactive, QPalette::Base, brush);
0087     p.setBrush(QPalette::Disabled, QPalette::Base, brush);
0088     setPalette(p);
0089 
0090     slotSetTransaction(0);
0091 }
0092 
0093 TransactionForm::~TransactionForm()
0094 {
0095     Q_D(TransactionForm);
0096     delete d;
0097 }
0098 
0099 bool TransactionForm::focusNextPrevChild(bool next)
0100 {
0101     return QFrame::focusNextPrevChild(next);
0102 }
0103 
0104 void TransactionForm::clear()
0105 {
0106     slotSetTransaction(0);
0107 }
0108 
0109 void TransactionForm::enableTabBar(bool b)
0110 {
0111     Q_D(TransactionForm);
0112     d->m_tabBar->setEnabled(b);
0113 }
0114 
0115 void TransactionForm::contentsMousePressEvent(QMouseEvent* ev)
0116 {
0117     ev->ignore();
0118 }
0119 
0120 void TransactionForm::contentsMouseMoveEvent(QMouseEvent* ev)
0121 {
0122     ev->ignore();
0123 }
0124 
0125 void TransactionForm::contentsMouseReleaseEvent(QMouseEvent* ev)
0126 {
0127     ev->ignore();
0128 }
0129 
0130 void TransactionForm::contentsMouseDoubleClickEvent(QMouseEvent* ev)
0131 {
0132     ev->ignore();
0133 }
0134 
0135 void TransactionForm::keyPressEvent(QKeyEvent* ev)
0136 {
0137     ev->ignore();
0138 }
0139 
0140 
0141 void TransactionForm::slotSetTransaction(KMyMoneyRegister::Transaction* transaction)
0142 {
0143     Q_D(TransactionForm);
0144     d->m_transaction = transaction;
0145 
0146     setUpdatesEnabled(false);
0147 
0148     if (d->m_transaction) {
0149         // the next call sets up a back pointer to the form and also sets up the col and row span
0150         // as well as the tab of the form
0151         d->m_transaction->setupForm(this);
0152 
0153     } else {
0154         setRowCount(5);
0155         setColumnCount(1);
0156     }
0157 
0158     KMyMoneyDateInput dateInput;
0159     KMyMoneyCategory category(true, nullptr);
0160 
0161     // extract the maximal sizeHint height
0162     int height = qMax(dateInput.sizeHint().height(), category.sizeHint().height());
0163 
0164     for (int row = 0; row < rowCount(); ++row) {
0165         if (!transaction || transaction->showRowInForm(row)) {
0166             showRow(row);
0167             QTableWidget::setRowHeight(row, height);
0168         } else
0169             hideRow(row);
0170     }
0171 
0172     // adjust vertical size of form table
0173     height *= rowCount();
0174     setMaximumHeight(height);
0175     setMinimumHeight(height);
0176 
0177     setUpdatesEnabled(true); // see the call to setUpdatesEnabled(false) above
0178 
0179     for (auto i = 0; i < rowCount(); ++i) {
0180         setItemDelegateForRow(i, d->m_itemDelegate);
0181     }
0182 
0183     // force resizeing of the columns
0184     QMetaObject::invokeMethod(this, "resize", Qt::QueuedConnection, QGenericReturnArgument(), Q_ARG(int, (int)eTransactionForm::Column::Value1));
0185 }
0186 
0187 void TransactionForm::paintCell(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)
0188 {
0189     Q_D(TransactionForm);
0190     if (d->m_transaction) {
0191         d->m_transaction->paintFormCell(painter, option, index);
0192     }
0193 }
0194 
0195 void TransactionForm::setCurrentCell(int, int)
0196 {
0197 }
0198 
0199 KMyMoneyTransactionForm::TabBar* TransactionForm::getTabBar(QWidget* parent)
0200 {
0201     Q_D(TransactionForm);
0202     if (!d->m_tabBar && parent) {
0203         // determine the height of the objects in the table
0204         // create the tab bar
0205         d->m_tabBar = new TabBar(parent);
0206         d->m_tabBar->setSignalEmission(eTabBar::SignalEmission::Always);
0207         QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
0208         sizePolicy.setHeightForWidth(d->m_tabBar->sizePolicy().hasHeightForWidth());
0209         d->m_tabBar->setSizePolicy(sizePolicy);
0210         connect(d->m_tabBar, &TabBar::tabCurrentChanged, this, &TransactionForm::slotActionSelected);
0211     }
0212     return d->m_tabBar;
0213 }
0214 
0215 void TransactionForm::slotActionSelected(int id)
0216 {
0217     emit newTransaction(static_cast<eRegister::Action>(id));
0218 }
0219 
0220 void TransactionForm::setupForm(const MyMoneyAccount& acc)
0221 {
0222     Q_D(TransactionForm);
0223     bool blocked = d->m_tabBar->blockSignals(true);
0224 
0225     // remove all tabs from the tabbar
0226     while (d->m_tabBar->count())
0227         d->m_tabBar->removeTab(0);
0228 
0229     d->m_tabBar->show();
0230 
0231     // important: one needs to add the new tabs first and then
0232     // change the identifier. Otherwise, addTab() will assign
0233     // a different value
0234     switch (acc.accountType()) {
0235     default:
0236         d->m_tabBar->insertTab((int)eRegister::Action::Deposit, i18n("&Deposit"));
0237         d->m_tabBar->insertTab((int)eRegister::Action::Transfer, i18n("&Transfer"));
0238         d->m_tabBar->insertTab((int)eRegister::Action::Withdrawal, i18n("&Withdrawal"));
0239         break;
0240 
0241     case eMyMoney::Account::Type::CreditCard:
0242         d->m_tabBar->insertTab((int)eRegister::Action::Deposit, i18n("&Payment"));
0243         d->m_tabBar->insertTab((int)eRegister::Action::Transfer, i18n("&Transfer"));
0244         d->m_tabBar->insertTab((int)eRegister::Action::Withdrawal, i18n("&Charge"));
0245         break;
0246 
0247     case eMyMoney::Account::Type::Liability:
0248     case eMyMoney::Account::Type::Loan:
0249         d->m_tabBar->insertTab((int)eRegister::Action::Deposit, i18n("&Decrease"));
0250         d->m_tabBar->insertTab((int)eRegister::Action::Transfer, i18n("&Transfer"));
0251         d->m_tabBar->insertTab((int)eRegister::Action::Withdrawal, i18n("&Increase"));
0252         break;
0253 
0254     case eMyMoney::Account::Type::Asset:
0255     case eMyMoney::Account::Type::AssetLoan:
0256         d->m_tabBar->insertTab((int)eRegister::Action::Deposit, i18n("&Increase"));
0257         d->m_tabBar->insertTab((int)eRegister::Action::Transfer, i18n("&Transfer"));
0258         d->m_tabBar->insertTab((int)eRegister::Action::Withdrawal, i18n("&Decrease"));
0259         break;
0260 
0261     case eMyMoney::Account::Type::Income:
0262     case eMyMoney::Account::Type::Expense:
0263     case eMyMoney::Account::Type::Investment:
0264     case eMyMoney::Account::Type::Stock:
0265         d->m_tabBar->hide();
0266         break;
0267     }
0268     d->m_tabBar->blockSignals(blocked);
0269 }
0270 
0271 void TransactionForm::resize(int col)
0272 {
0273     setUpdatesEnabled(false);
0274 
0275     // resize the register
0276     int w = viewport()->width();
0277     int nc = columnCount();
0278 
0279     // check which space we need
0280     if (nc >= (int)eTransactionForm::Column::Label1 && columnWidth((int)eTransactionForm::Column::Label1))
0281         adjustColumn(eTransactionForm::Column::Label1);
0282     if (nc >= (int)eTransactionForm::Column::Value1 && columnWidth((int)eTransactionForm::Column::Value1))
0283         adjustColumn(eTransactionForm::Column::Value1);
0284     if (nc >= (int)eTransactionForm::Column::Label2 && columnWidth((int)eTransactionForm::Column::Label2))
0285         adjustColumn(eTransactionForm::Column::Label2);
0286     if (nc >= (int)eTransactionForm::Column::Value2 && columnWidth((int)eTransactionForm::Column::Value2))
0287         adjustColumn(eTransactionForm::Column::Value2);
0288 
0289     for (auto i = 0; i < nc; ++i) {
0290         if (i == col)
0291             continue;
0292 
0293         w -= columnWidth(i);
0294     }
0295     if (col < nc && w >= 0)
0296         setColumnWidth(col, w);
0297 
0298     setUpdatesEnabled(true);
0299 }
0300 
0301 void TransactionForm::paintFocus(QPainter* /*p*/, const QRect& /*cr*/)
0302 {
0303 }
0304 
0305 void TransactionForm::adjustColumn(eTransactionForm::Column col)
0306 {
0307     Q_D(TransactionForm);
0308     int w = 0;
0309 
0310     // preset the width of the right value column with the width of
0311     // the possible edit widgets so that they fit if they pop up
0312     if (col == eTransactionForm::Column::Value2) {
0313         KMyMoneyDateInput dateInput;
0314         AmountEdit valInput;
0315         w = qMax(dateInput.sizeHint().width(), valInput.sizeHint().width());
0316     }
0317 
0318     if (d->m_transaction) {
0319         QString txt;
0320         QFontMetrics fontMetrics(KMyMoneySettings::listCellFontEx());
0321 
0322         // scan through the rows
0323         for (int i = rowCount() - 1; i >= 0; --i) {
0324             Qt::Alignment align;
0325             int spacing = 10;
0326             d->m_transaction->formCellText(txt, align, i, static_cast<int>(col), 0);
0327             QWidget* cw = cellWidget(i, (int)col);
0328             if (cw) {
0329                 w = qMax(w, cw->sizeHint().width() + spacing);
0330                 // if the cell widget contains a push button increase the spacing used
0331                 // for the cell text value to consider the size of the push button
0332                 if (QPushButton *pushButton = cw->findChild<QPushButton *>()) {
0333                     spacing += pushButton->sizeHint().width() + 5;
0334                 }
0335             }
0336             w = qMax(w, fontMetrics.width(txt) + spacing);
0337         }
0338     }
0339 
0340     if ((int)col < columnCount())
0341         setColumnWidth((int)col, w);
0342 }
0343 
0344 void TransactionForm::arrangeEditWidgets(QMap<QString, QWidget*>& editWidgets, KMyMoneyRegister::Transaction* t)
0345 {
0346     t->arrangeWidgetsInForm(editWidgets);
0347     resize((int)eTransactionForm::Column::Value1);
0348 }
0349 
0350 void TransactionForm::tabOrder(QWidgetList& tabOrderWidgets, KMyMoneyRegister::Transaction* t) const
0351 {
0352     t->tabOrderInForm(tabOrderWidgets);
0353 }
0354 
0355 void TransactionForm::removeEditWidgets(QMap<QString, QWidget*>& editWidgets)
0356 {
0357     QMap<QString, QWidget*>::iterator it;
0358     for (it = editWidgets.begin(); it != editWidgets.end();) {
0359         if ((*it)->parentWidget() == this) {
0360             editWidgets.erase(it);
0361             it = editWidgets.begin();
0362         } else
0363             ++it;
0364     }
0365 
0366     for (int row = 0; row < rowCount(); ++row) {
0367         for (int col = 0; col < columnCount(); ++col) {
0368             if (cellWidget(row, col)) {
0369                 cellWidget(row, col)->hide();
0370                 setCellWidget(row, col, 0);
0371             }
0372         }
0373     }
0374     resize((int)eTransactionForm::Column::Value1);
0375 
0376     // delete all remaining edit widgets   (e.g. tabbar)
0377     for (it = editWidgets.begin(); it != editWidgets.end();) {
0378         delete(*it);  // ->deleteLater();
0379         editWidgets.erase(it);
0380         it = editWidgets.begin();
0381     }
0382 }